all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Better way to make sure external command exists in the system?
@ 2021-03-18 12:13 Jean Louis
  2021-03-19 13:57 ` Daniel Martín
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-18 12:13 UTC (permalink / raw)
  To: Help GNU Emacs

I have changed the OS on one computer and noticed that my Emacs Lisp
programs use external commands like: mailutils, mail, pandoc,
markdown, and others. Sometimes I was hard coding the path names like
/usr/local/bin and now some commands changed to /usr/bin

And some functions should not even run if external command does not
exist. I would even like to stop loading the .el program if necessary
external programs do not exist in the system.

For that reason I would do some changes:

- instead of hard coding the program name within quotes, I will use
  variable. Instead of (shell-command "mogrify ...") I will rather use
  something like (shell-command (format "%s ..." mogrify-command))

- variables for commands I would place at beginning of programs

- before variables get defined, I would use `executable-find' but I
  would like for the program loading to fail if those external
  programs cannot be found.

Is it then recommended to use something like:

(defun check-my-executables ()
  ...)

(check-my-executables)

during the loading time?

Jean










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

* Re: Better way to make sure external command exists in the system?
  2021-03-18 12:13 Better way to make sure external command exists in the system? Jean Louis
@ 2021-03-19 13:57 ` Daniel Martín
  2021-03-19 14:16   ` 2QdxY4RzWzUUiLuE
  2021-03-21 14:07   ` Jean Louis
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Martín @ 2021-03-19 13:57 UTC (permalink / raw)
  To: Jean Louis; +Cc: Help GNU Emacs

Jean Louis <bugs@gnu.support> writes:

> I have changed the OS on one computer and noticed that my Emacs Lisp
> programs use external commands like: mailutils, mail, pandoc,
> markdown, and others. Sometimes I was hard coding the path names like
> /usr/local/bin and now some commands changed to /usr/bin
>
> And some functions should not even run if external command does not
> exist. I would even like to stop loading the .el program if necessary
> external programs do not exist in the system.
>
> For that reason I would do some changes:
>
> - instead of hard coding the program name within quotes, I will use
>   variable. Instead of (shell-command "mogrify ...") I will rather use
>   something like (shell-command (format "%s ..." mogrify-command))
>
> - variables for commands I would place at beginning of programs
>

Yes, I think that using a variable instead of a hardcoded string is
recommended.

> - before variables get defined, I would use `executable-find' but I
>   would like for the program loading to fail if those external
>   programs cannot be found.

Why do you think that checking for the existence of programs on load is
better? I think it would slow down loading the module, and the benefits
are not clear to me.  For example, the Elisp module may still be useful
even if it cannot call external programs.

Why is it better than simply calling `executable-find' when invoking a
command that depends on an external program?



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

* Re: Better way to make sure external command exists in the system?
  2021-03-19 13:57 ` Daniel Martín
@ 2021-03-19 14:16   ` 2QdxY4RzWzUUiLuE
  2021-03-21 14:10     ` Jean Louis
  2021-03-21 14:07   ` Jean Louis
  1 sibling, 1 reply; 15+ messages in thread
From: 2QdxY4RzWzUUiLuE @ 2021-03-19 14:16 UTC (permalink / raw)
  To: help-gnu-emacs

On 2021-03-19 at 14:57:34 +0100,
Daniel Martín <mardani29@yahoo.es> wrote:

> Jean Louis <bugs@gnu.support> writes:
> 
> > I have changed the OS on one computer and noticed that my Emacs Lisp
> > programs use external commands like: mailutils, mail, pandoc,
> > markdown, and others. Sometimes I was hard coding the path names like
> > /usr/local/bin and now some commands changed to /usr/bin
> >
> > And some functions should not even run if external command does not
> > exist. I would even like to stop loading the .el program if necessary
> > external programs do not exist in the system.
> >
> > For that reason I would do some changes:
> >
> > - instead of hard coding the program name within quotes, I will use
> >   variable. Instead of (shell-command "mogrify ...") I will rather use
> >   something like (shell-command (format "%s ..." mogrify-command))
> >
> > - variables for commands I would place at beginning of programs
> >
> 
> Yes, I think that using a variable instead of a hardcoded string is
> recommended.
> 
> > - before variables get defined, I would use `executable-find' but I
> >   would like for the program loading to fail if those external
> >   programs cannot be found.
> 
> Why do you think that checking for the existence of programs on load is
> better? I think it would slow down loading the module, and the benefits
> are not clear to me.  For example, the Elisp module may still be useful
> even if it cannot call external programs.
> 
> Why is it better than simply calling `executable-find' when invoking a
> command that depends on an external program?

Using executable-find at load time is better because modules are only
loaded once, but the functionality inside the modules is executed
repeatedly.  Personally, my emacs.el loads lots of stuff
unconditionally, because I usually only start Emacs when I start my X
session, which is already time consuming.  Anything I don't load at that
time only delays me later.

And if every function in a module is a wrapper around, say, mogrify,
then why shouldn't I verfiy that mogrify exists before I load the
module?  (Obviously, there are a number of user- and application-
interface questions to be answered, but there are definitely modules
that can't do anything (except report failure) without their associated
external dependencies.)



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

* Re: Better way to make sure external command exists in the system?
  2021-03-19 13:57 ` Daniel Martín
  2021-03-19 14:16   ` 2QdxY4RzWzUUiLuE
@ 2021-03-21 14:07   ` Jean Louis
  2021-03-21 17:16     ` Emanuel Berg via Users list for the GNU Emacs text editor
  1 sibling, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-21 14:07 UTC (permalink / raw)
  To: Daniel Martín; +Cc: Help GNU Emacs

* Daniel Martín <mardani29@yahoo.es> [2021-03-19 16:59]:
> > - before variables get defined, I would use `executable-find' but I
> >   would like for the program loading to fail if those external
> >   programs cannot be found.
> 
> Why do you think that checking for the existence of programs on load is
> better? I think it would slow down loading the module, and the benefits
> are not clear to me.  For example, the Elisp module may still be useful
> even if it cannot call external programs.
> 
> Why is it better than simply calling `executable-find' when invoking a
> command that depends on an external program?

I would not like later invoking functions that don't work. But I do
the checks in the functions. Sometimes majority of functions belong in
the same domain that uses external commands.

(defun rcd-which-list (command-list)
  "Verifies that list of shell commands COMMAND-LIST exist in
user's $PATH"
  (let ((all-exist t))
    (dolist (command command-list all-exist)
      (unless (executable-find command)
	(setq all-exist nil)
	(rcd-warning-message "Shell command `%s' does not exist" command)))))

(defun optimize-image-jpg (file)
  "Optimizes the JPG image with quality 70%"
  (if (rcd-which-list '("mogrify"))
      (let ((extension (file-name-extension file)))
	(when (equal (downcase extension) "jpg")
	  (let* ((file (shell-double-quote file))
		 (command (format "mogrify -sampling-factor 4:2:0 -strip -interlace JPEG -colorspace RGB -quality 70 \"%s\"" file)))
	    (message command)
	    (shell-command command))))
    (rcd-warning-message "RCD ERROR: `mogrify' not found in $PATH")))

(defun optimize-jpg-images-dired ()
  "Optimizes JPG images inside of Dired"
  (interactive)
  (let ((files (dired-get-marked-files)))
    (dolist (file files)
      (optimize-image-jpg file))
    (revert-buffer)))

(defun image-resize (file &optional size)
  "Resizes the JPG image with default size"
  (if (rcd-which-list '("mogrify"))
      (let ((extension (file-name-extension file)))
	(when (or (equal (downcase extension) "jpg")
		  (equal (downcase extension) "png"))
	  (let* ((file (shell-double-quote file))
		 (command (format "mogrify -resize %s \"%s\"" size file)))
	    (message command)
	    (call-process-shell-command command))))
    (rcd-warning-message "RCD ERROR: `mogrify' not found in `$PATH'")))
    
(defun image-resize-dired ()
  "Resizes images"
  (interactive)
  (let ((files (dired-get-marked-files))
	(size (read-number "Size: " *image-default-resize-size* '(*image-resize-sizes*))))
    (dolist (file files)
      (image-resize file size))
    (revert-buffer)))

(defun rcd-play-sound-bg (file)
  "Plays found file in background"
  (let ((play (executable-find "play")))
    (if play
	  (let ((command (format "play \"%s\"" file)))
	    (async-shell-command command))
      (message "RCD ERROR: `play' not found in $PATH"))))

(defun rcd-warning-message (format-string &rest message)
  "Plays a warning sound while using function `message' as
usual."
  (rcd-play-sound-bg rcd-warning-message-sound-file)
  (apply 'message format-string message))



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

* Re: Better way to make sure external command exists in the system?
  2021-03-19 14:16   ` 2QdxY4RzWzUUiLuE
@ 2021-03-21 14:10     ` Jean Louis
  2021-03-21 17:17       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-21 14:10 UTC (permalink / raw)
  To: help-gnu-emacs

* 2QdxY4RzWzUUiLuE@potatochowder.com <2QdxY4RzWzUUiLuE@potatochowder.com> [2021-03-19 17:18]:
> Using executable-find at load time is better because modules are only
> loaded once, but the functionality inside the modules is executed
> repeatedly.

And how to practically prevent loading if external commands are not
available?

What is best approach?




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

* Re: Better way to make sure external command exists in the system?
  2021-03-21 14:07   ` Jean Louis
@ 2021-03-21 17:16     ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-03-23  8:02       ` Jean Louis
  0 siblings, 1 reply; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-21 17:16 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

> I would not like later invoking functions that don't work.
> But I do the checks in the functions. Sometimes majority of
> functions belong in the same domain that uses
> external commands.
>
> (defun rcd-which-list (command-list)
>   "Verifies that list of shell commands COMMAND-LIST exist in
> user's $PATH"
>   (let ((all-exist t))
>     (dolist (command command-list all-exist)
>       (unless (executable-find command)
> 	(setq all-exist nil)
> 	(rcd-warning-message "Shell command `%s' does not exist" command)))))
>
> [and much more Elisp]

I'll read it, if you fix all this first...

byte compiler:

geh.el: 
In image-resize-dired:
geh.el:324:32: Warning: reference to free variable
    ‘*image-default-resize-size*’

In rcd-warning-message:
geh.el:340:22: Warning: reference to free variable
    ‘rcd-warning-message-sound-file’

In end of data:
geh.el:342:1: Warning: the following functions are not known to be defined:
    shell-double-quote, dired-get-marked-files

checkdoc: [see lines 52-62 here https://dataswamp.org/~incal/emacs-init/ide/elisp.el]

geh.el:281: First line is not a complete sentence
geh.el:290: First sentence should end with punctuation
geh.el:290: Argument ‘file’ should appear (as FILE) in the doc string
geh.el:301: First sentence should end with punctuation
geh.el:309: First sentence should end with punctuation
geh.el:309: Argument ‘file’ should appear (as FILE) in the doc string
geh.el:321: First sentence should end with punctuation
geh.el:330: First sentence should end with punctuation
geh.el:330: Argument ‘file’ should appear (as FILE) in the doc string
geh.el:338: First line is not a complete sentence
geh.el:338: Argument ‘format-string’ should appear (as FORMAT-STRING) in the doc string

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: Better way to make sure external command exists in the system?
  2021-03-21 14:10     ` Jean Louis
@ 2021-03-21 17:17       ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-21 17:17 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

>> Using executable-find at load time is better because
>> modules are only loaded once, but the functionality inside
>> the modules is executed repeatedly.
>
> And how to practically prevent loading if external commands
> are not available?

Easy. But fix the code first please.

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: Better way to make sure external command exists in the system?
  2021-03-21 17:16     ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-03-23  8:02       ` Jean Louis
  2021-03-23  9:56         ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-23  8:02 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-03-21 20:18]:
> Jean Louis wrote:
> 
> > I would not like later invoking functions that don't work.
> > But I do the checks in the functions. Sometimes majority of
> > functions belong in the same domain that uses
> > external commands.
> >
> > (defun rcd-which-list (command-list)
> >   "Verifies that list of shell commands COMMAND-LIST exist in
> > user's $PATH"
> >   (let ((all-exist t))
> >     (dolist (command command-list all-exist)
> >       (unless (executable-find command)
> > 	(setq all-exist nil)
> > 	(rcd-warning-message "Shell command `%s' does not exist" command)))))
> >
> > [and much more Elisp]
> 
> I'll read it, if you fix all this first...
> 
> byte compiler:
> 
> geh.el: 
> In image-resize-dired:
> geh.el:324:32: Warning: reference to free variable
>     ‘*image-default-resize-size*’

;;; image-resize-dired.el --- Function to resize images in Dired
;; dired-get-marked-files is in dired

;;; Commentary:
;; 

;;; Code:

(require 'dired)

(defvar *image-default-resize-size* 1536)
(defvar *image-resize-sizes* '("1536" "1024" "800" "1200" "640"))

;; Place your warning sound file yourself
(defcustom rcd-warning-message-sound-file nil
  "The sound file for warning messages."
  :group 'rcd
  :type 'string)

(defun image-resize (file &optional size)
  "Resizes the JPG image with default SIZE.
Argument FILE is image to be resized."
  (if (rcd-which-list '("mogrify"))
      (let ((extension (file-name-extension file)))
	(when (or (equal (downcase extension) "jpg")
		  (equal (downcase extension) "png"))
	  (let* ((file (shell-double-quote file))
		 (command (format "mogrify -resize %s \"%s\"" size file)))
	    (message command)
	    (call-process-shell-command command))))
    (rcd-warning-message "RCD ERROR: `mogrify' not found in `$PATH'")))

(defun image-resize-dired ()
  "Resizes images."
  (interactive)
  (let ((files (dired-get-marked-files))
	(size (read-number "Size: " *image-default-resize-size* '(*image-resize-sizes*))))
    (dolist (file files)
      (image-resize file size))
    (revert-buffer)))

(defun shell-double-quote (s)
  "Double quotes for the string that shall be fed to shell command.
Argument S is string."
  (replace-regexp-in-string "\"" "\\\\\"" s))

(provide 'image-resize-dired)

;;; image-resize-dired.el ends here



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

* Re: Better way to make sure external command exists in the system?
  2021-03-23  8:02       ` Jean Louis
@ 2021-03-23  9:56         ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-03-23 10:13           ` Jean Louis
  0 siblings, 1 reply; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-23  9:56 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

OK, let's see, straight X-Mas Eve this...

> (defvar *image-default-resize-size* 1536)
> (defvar *image-resize-sizes* '("1536" "1024" "800" "1200" "640"))

The *common-lisp-convention* for global variables is
disencourage in Elisp.

Also, why the strings?

> Argument FILE is image to be resized."
>   (if (rcd-which-list '("mogrify"))

Not known to be defined: rcd-which-list (indeed I don't have it)
Same with rcd-warning-message.

>       (let ((extension (file-name-extension file)))
> 	(when (or (equal (downcase extension) "jpg")
> 		  (equal (downcase extension) "png"))

Same thing twice, instead do let*.

> (defun image-resize-dired ()
>   "Resizes images."
>   (interactive)
>   (let ((files (dired-get-marked-files))
> 	(size (read-number "Size: " *image-default-resize-size* '(*image-resize-sizes*))))

HIST isn't used like that what I can see, read the
`read-from-minibuffer' docstring. Does it even work?

Also, why `read-number' and not in interactive?

And, no need for globals if they are only used here. Use let*
for that as well.

Keep it on...

-- 
underground experts united
http://user.it.uu.se/~embe8573
https://dataswamp.org/~incal




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

* Re: Better way to make sure external command exists in the system?
  2021-03-23  9:56         ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-03-23 10:13           ` Jean Louis
  2021-03-25 15:01             ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-23 10:13 UTC (permalink / raw)
  To: help-gnu-emacs

Hello,

Thanks for noticing, I did not. It was work in progress and I was
mostly resizing to 1536 and did not even touch those other sizes.

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-03-23 12:58]:
> Jean Louis wrote:
> 
> OK, let's see, straight X-Mas Eve this...
> 
> > (defvar *image-default-resize-size* 1536)
> > (defvar *image-resize-sizes* '("1536" "1024" "800" "1200" "640"))

Now it is:

(defvar image-default-resize-size "1536")
(defvar image-resize-sizes '("1536" "1024" "800" "1200" "640"))

> The *common-lisp-convention* for global variables is
> disencourage in Elisp.

Yes, those functions are old. Who knows what I knew back then.

> Also, why the strings?

Maybe it works with numbers, but now I changed it to completing-read,
maybe that is why I placed it as strings.

(defun image-resize-dired ()
  "Resizes images."
  (interactive)
  (let ((files (dired-get-marked-files))
	(size (completing-read "Size: " image-resize-sizes nil t image-default-resize-size)))
    (dolist (file files)
      (image-resize file size))
    (revert-buffer)))

That way is better, my choice of 1536 is offered, but if I delete it,
I can complete it with some of other default choices. It is very handy
to mark files and resize them how one wants.

Optimizing them helps to make them perfect for online, optimized
images are then bringing more customers from search engines, as they
respect optimized websites.

(defun optimize-image-jpg (file)
  "Optimizes the JPG image with quality 70%"
  (if (rcd-which-list '("mogrify"))
      (let ((extension (file-name-extension file)))
	(when (equal (downcase extension) "jpg")
	  (let* ((file (shell-double-quote file))
		 (command (format "mogrify -sampling-factor 4:2:0 -strip -interlace JPEG -colorspace RGB -quality 70 \"%s\"" file)))
	    (message command)
	    (shell-command command))))
    (rcd-warning-message "RCD ERROR: `mogrify' not found in $PATH")))

(defun optimize-jpg-images-dired ()
  "Optimizes JPG images inside of Dired"
  (interactive)
  (let ((files (dired-get-marked-files)))
    (dolist (file files)
      (optimize-image-jpg file))
    (revert-buffer)))

> > Argument FILE is image to be resized."
> >   (if (rcd-which-list '("mogrify"))
> 
> Not known to be defined: rcd-which-list (indeed I don't have it)
> Same with rcd-warning-message.

(defun rcd-which-list (command-list)
  "Verifies that list of shell commands COMMAND-LIST exist in
user's $PATH"
  (let ((all-exist t))
    (dolist (command command-list all-exist)
      (unless (executable-find command)
	(setq all-exist nil)
	(rcd-warning-message "Shell command `%s' does not exist" command)))))

> >       (let ((extension (file-name-extension file)))
> > 	(when (or (equal (downcase extension) "jpg")
> > 		  (equal (downcase extension) "png"))
> 
> Same thing twice, instead do let*.

There I wanted to test first for extension and then to proceed. 

> > (defun image-resize-dired ()
> >   "Resizes images."
> >   (interactive)
> >   (let ((files (dired-get-marked-files))
> > 	(size (read-number "Size: " *image-default-resize-size* '(*image-resize-sizes*))))
> 
> HIST isn't used like that what I can see, read the
> `read-from-minibuffer' docstring. Does it even work?

That is something you noticed, I did not, I was resizing for quite a
long time to 1536 and never bothered. But now it works. It was meant
to complete with various default sizes for resizing.

> Also, why `read-number' and not in interactive?

I often use `completing-read', maybe that may be implemented in
`interactive' but I don't find it nice that way.

> And, no need for globals if they are only used here. Use let*
> for that as well.

Which globals?


Jean



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

* Re: Better way to make sure external command exists in the system?
  2021-03-23 10:13           ` Jean Louis
@ 2021-03-25 15:01             ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-03-25 15:17               ` Jean Louis
  0 siblings, 1 reply; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-25 15:01 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

> Now it is:
>
> (defvar image-default-resize-size "1536")
> (defvar image-resize-sizes '("1536" "1024" "800" "1200" "640"))

Well, the width of a computer image is not a string but
an integer.

>> The *common-lisp-convention* for global variables is
>> disencourage in Elisp.
>
> Yes, those functions are old. Who knows what I knew
> back then.

Yeah, it is always like that...

>> Also, why the strings?
>
> Maybe it works with numbers, but now I changed it to
> completing-read, maybe that is why I placed it as strings.

Don't do that, data should be in its natural, sound state,
then it is up to functions and/or users who use it to convert
it to fit their purposes. And the better everything is, the
less of that is required.

> (defun image-resize-dired ()
>   "Resizes images."
>   (interactive)
>   (let ((files (dired-get-marked-files))
> 	(size (completing-read "Size: " image-resize-sizes nil t image-default-resize-size)))
>     (dolist (file files)
>       (image-resize file size))
>     (revert-buffer)))
>
> That way is better, my choice of 1536 is offered, but if
> I delete it, I can complete it with some of other default
> choices. It is very handy to mark files and resize them how
> one wants.

OK, not sure that's the way it is supposed to work but if you
want to innovate, no problem.

> (defun optimize-image-jpg (file)
>   "Optimizes the JPG image with quality 70%"
>   (if (rcd-which-list '("mogrify"))
>       (let ((extension (file-name-extension file)))
> 	(when (equal (downcase extension) "jpg")
> 	  (let* ((file (shell-double-quote file))
> 		 (command (format "mogrify -sampling-factor 4:2:0 -strip -interlace JPEG -colorspace RGB -quality 70 \"%s\"" file)))
> 	    (message command)
> 	    (shell-command command))))
>     (rcd-warning-message "RCD ERROR: `mogrify' not found in $PATH")))
>
> (defun optimize-jpg-images-dired ()
>   "Optimizes JPG images inside of Dired"
>   (interactive)
>   (let ((files (dired-get-marked-files)))
>     (dolist (file files)
>       (optimize-image-jpg file))
>     (revert-buffer)))

geh.el:281: First sentence should end with punctuation
geh.el:281: Argument ‘file’ should appear (as FILE) in the doc string
geh.el:292: First sentence should end with punctuation

Otherwise looks good, I don't have dired-get-marked-files,
rcd-warning-message, rcd-which-list, or shell-double-quote but
I suppose you do...

>>> 		  (equal (downcase extension) "png"))
>> 
>> Same thing twice, instead do let*.
>
> There I wanted to test first for extension and then to proceed. 

Yes, but put (downcase extension) in a let* and so you don't
have to do it twice. Now you seem to have removed the PNG so
it isn't an issue anymore.

>> Also, why `read-number' and not in interactive?
>
> I often use `completing-read', maybe that may be implemented in
> `interactive' but I don't find it nice that way.

Yes, compare:

(interactive
  `(,(string-to-number
       (completing-read "Digit: " '("11" "12" "13") nil t "11"))))

>> And, no need for globals if they are only used here.
>> Use let* for that as well.
>
> Which globals?

The two global variables.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Better way to make sure external command exists in the system?
  2021-03-25 15:01             ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-03-25 15:17               ` Jean Louis
  2021-03-25 20:47                 ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-25 15:17 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-03-25 18:04]:
> Jean Louis wrote:
> 
> > Now it is:
> >
> > (defvar image-default-resize-size "1536")
> > (defvar image-resize-sizes '("1536" "1024" "800" "1200" "640"))
> 
> Well, the width of a computer image is not a string but
> an integer.

Maybe yes, maybe not, but it does not matter neither for human or
computer. Human sees the number at completion.

> > Maybe it works with numbers, but now I changed it to
> > completing-read, maybe that is why I placed it as strings.
> 
> Don't do that, data should be in its natural, sound state,
> then it is up to functions and/or users who use it to convert
> it to fit their purposes. And the better everything is, the
> less of that is required.

In general yes, but in this specific case, who cares, important is
that it works. Numbers or strings are converted to string by using
format. One can supply either integer or string, it does not matter,
it works. See:

(defun image-resize (file &optional size)
  "Resizes the JPG image with default SIZE.
Argument FILE is image to be resized."
  (if (rcd-which-list '("mogrify"))
      (let ((extension (file-name-extension file)))
	(when (or (equal (downcase extension) "jpg")
		  (equal (downcase extension) "png"))
	  (let* ((file (shell-double-quote file))
		 (command (format "mogrify -resize %s \"%s\"" size file)))
	    (message command)
	    (call-process-shell-command command))))
    (rcd-warning-message "RCD ERROR: `mogrify' not found in `$PATH'")))

> > (defun image-resize-dired ()
> >   "Resizes images."
> >   (interactive)
> >   (let ((files (dired-get-marked-files))
> > 	(size (completing-read "Size: " image-resize-sizes nil t image-default-resize-size)))
> >     (dolist (file files)
> >       (image-resize file size))
> >     (revert-buffer)))
> >
> > That way is better, my choice of 1536 is offered, but if
> > I delete it, I can complete it with some of other default
> > choices. It is very handy to mark files and resize them how
> > one wants.
> 
> OK, not sure that's the way it is supposed to work but if you
> want to innovate, no problem.

I want to be able to complete straight. `read-number' does not offer
completion.

This does not work:

(completing-read "Number: " '(1 2 3))

This works:

(completing-read "Number: " '("1" "2" "3"))

Now you get it why they are strings in the completion list? They are
not strings for the underlying function `image-resize' but only for
the completion candidates.

> Otherwise looks good, I don't have dired-get-marked-files,

It is in dired.

> rcd-warning-message, rcd-which-list, or shell-double-quote but
> I suppose you do...

I gave you recently if you need.

> >> Also, why `read-number' and not in interactive?
> >
> > I often use `completing-read', maybe that may be implemented in
> > `interactive' but I don't find it nice that way.
> 
> Yes, compare:
> 
> (interactive
>   `(,(string-to-number
>        (completing-read "Digit: " '("11" "12" "13") nil t "11"))))

That would mean if I change candidates list I would actually need to
change the function. Not practical. 🙈 But interesting.

> >> And, no need for globals if they are only used here.
> >> Use let* for that as well.
> >
> > Which globals?
> 
> The two global variables.

I would not know which...



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

* Re: Better way to make sure external command exists in the system?
  2021-03-25 15:17               ` Jean Louis
@ 2021-03-25 20:47                 ` Emanuel Berg via Users list for the GNU Emacs text editor
  2021-03-25 20:56                   ` Jean Louis
  0 siblings, 1 reply; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-25 20:47 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

>>> Now it is:
>>>
>>> (defvar image-default-resize-size "1536")
>>> (defvar image-resize-sizes '("1536" "1024" "800" "1200" "640"))
>> 
>> Well, the width of a computer image is not a string but
>> an integer.
>
> Maybe yes, maybe not, but it does not matter neither for
> human or computer. Human sees the number at completion.

...

>>> Maybe it works with numbers, but now I changed it to
>>> completing-read, maybe that is why I placed it as strings.
>> 
>> Don't do that, data should be in its natural, sound state,
>> then it is up to functions and/or users who use it to
>> convert it to fit their purposes. And the better everything
>> is, the less of that is required.
>
> In general yes, but in this specific case, who cares

... >:[

> This does not work:
>
> (completing-read "Number: " '(1 2 3))
>
> This works:
>
> (completing-read "Number: " '("1" "2" "3"))
>
> Now you get it

... >:[

> why they are strings in the completion list? They are not
> strings for the underlying function `image-resize' but only
> for the completion candidates.

Use a set function

  (cl-map 'list #'number-to-string '(1 2 3)) ; ("1" "2" "3")

>> Yes, compare:
>> 
>> (interactive
>>   `(,(string-to-number
>>        (completing-read "Digit: " '("11" "12" "13") nil t "11"))))
>
> That would mean if I change candidates list I would actually
> need to change the function. Not practical.

... just unheard of

>>>> And, no need for globals if they are only used here.
>>>> Use let* for that as well.
>>>
>>> Which globals?
>> 
>> The two global variables.
>
> I would not know which...

I give up.

-- 
underground experts united
https://dataswamp.org/~incal




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

* Re: Better way to make sure external command exists in the system?
  2021-03-25 20:47                 ` Emanuel Berg via Users list for the GNU Emacs text editor
@ 2021-03-25 20:56                   ` Jean Louis
  2021-03-25 21:10                     ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 15+ messages in thread
From: Jean Louis @ 2021-03-25 20:56 UTC (permalink / raw)
  To: help-gnu-emacs

* Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> [2021-03-25 23:49]:
> Use a set function
> 
>   (cl-map 'list #'number-to-string '(1 2 3)) ; ("1" "2" "3")

But why use Emacs Lisp CL library and complexer Common Lisp style
when it works this way simpler:

(mapcar #'number-to-string '(1 2 3)) → ("1" "2" "3")

Any reason?

Then if I am to use some function defined in Emacs Lisp, then I
would rather use this one, instead of `cl-map', as it is simpler,
it will recognize the sequence.

(seq-map #'number-to-string '(1 2 3)) → ("1" "2" "3")




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

* Re: Better way to make sure external command exists in the system?
  2021-03-25 20:56                   ` Jean Louis
@ 2021-03-25 21:10                     ` Emanuel Berg via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 15+ messages in thread
From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-03-25 21:10 UTC (permalink / raw)
  To: help-gnu-emacs

Jean Louis wrote:

>> Use a set function
>> 
>>   (cl-map 'list #'number-to-string '(1 2 3)) ; ("1" "2" "3")
>
> But why use Emacs Lisp CL library and complexer Common Lisp
> style when it works this way simpler:
>
> (mapcar #'number-to-string '(1 2 3)) → ("1" "2" "3")
>
> Any reason?
>
> Then if I am to use some function defined in Emacs Lisp,
> then I would rather use this one, instead of `cl-map', as it
> is simpler, it will recognize the sequence.
>
> (seq-map #'number-to-string '(1 2 3)) → ("1" "2" "3")

Sure, use the one you like the best.

Post the code again when you are done.

-- 
underground experts united
https://dataswamp.org/~incal




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

end of thread, other threads:[~2021-03-25 21:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-18 12:13 Better way to make sure external command exists in the system? Jean Louis
2021-03-19 13:57 ` Daniel Martín
2021-03-19 14:16   ` 2QdxY4RzWzUUiLuE
2021-03-21 14:10     ` Jean Louis
2021-03-21 17:17       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-03-21 14:07   ` Jean Louis
2021-03-21 17:16     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-03-23  8:02       ` Jean Louis
2021-03-23  9:56         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-03-23 10:13           ` Jean Louis
2021-03-25 15:01             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-03-25 15:17               ` Jean Louis
2021-03-25 20:47                 ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-03-25 20:56                   ` Jean Louis
2021-03-25 21:10                     ` Emanuel Berg via Users list for the GNU Emacs text editor

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.