0

I could not figure out how to get a list out of this (my/tf :str nil "foo" ).

This function returns a concatenated string of directories or a list.

Function Must:

  1. Return a string when one argument is given OR :str t
  2. Return a list when more than 1 argument is given OR :str nil
(cl-defun my/tf (&rest rest  &key (str "_") (ex t)  &allow-other-keys )
(let ((new-list (cl-remove-if-not #'stringp rest))
      (dir user-emacs-directory ))
  (if rest (if (and  (not (equal str t)) (< 1 (length new-list) )) ; Return list when more than one arg.
              ;; Return list
               (mapcar (lambda (str-arg)
                          (if ex (expand-file-name str-arg dir )
                                 (concat (abbreviate-file-name dir) str-arg )
                              )) new-list)
              ;; Return string - Concat arguments separated by space.
               (mapconcat (lambda (str-arg)
                          (if ex (expand-file-name str-arg dir )
                                 (concat (abbreviate-file-name dir) str-arg )
                              )) new-list " "))
          (expand-file-name user-emacs-directory))))
           
;; WORKS
(my/tf "foo" "bar" ) ;("/home/rick/.config/emacs/foo" "/home/rick/.config/emacs/bar")
(my/tf "foo" ) ; ⇒ "/home/rick/.config/emacs/foo"
(my/tf  :str t "foo" ) ; ⇒ "/home/rick/.config/emacs/foo"
(my/tf :ex nil "foo" "bar" ) ; ⇒ ("~/.config/emacs/foo" "~/.config/emacs/bar")
(my/tf :ex nil :str t "foo" "bar" ) ; ⇒ "~/.config/emacs/foo ~/.config/emacs/bar"

;; DON’T WORK
;; When I use the (or (= 1 (length new-list) )(< 1 (length new-list)))
;; it messes the other ones up.
; Need a list when :str nil  ⇒ ("/home/rick/.config/emacs/foo")
(my/tf  :str nil "foo" ) ; ⇒ "/home/rick/.config/emacs/foo"
5
  • You're returning a list if str is not t and the length of the list is 2 or more. If you want to test "str is nil" on its own, then you need to do that. (It's not clear whether you want "str is nil" or "str is not t", but if the former then (not :str) tests that.)
    – phils
    Mar 6, 2023 at 21:15
  • @phils Thanks you gave me a good idea. I think I got it now, added a cond to fix it.
    – Rick
    Mar 6, 2023 at 21:57
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Mar 6, 2023 at 22:22
  • @Drew how would I go about asking a question such as the one I have? When I have a problem with a snippet? If this is ONLY for questions about Emacs Lisp as a language.
    – Rick
    Mar 6, 2023 at 22:27
  • Your question is about how to do something, perhaps including how to debug something you tried. The keywords have to do with what your problem is, what you're trying to do, what obstacles you've encountered, something specific you don't understand, or something about some particular element of the Lisp language (elisp-macros, defun, options, let-binding, etc.). Your question is not about Elisp as a variety of Lisp, i.e., compared with other Lisps. It looks like your question is maybe about lists and using conditionals.
    – Drew
    Mar 7, 2023 at 2:11

1 Answer 1

1

I ended up using cond to fix it. Here is the full working code.

(cl-defun my/tf (&rest rest  &key (str "_") (ex t)  &allow-other-keys )
  (let ((new-list (cl-remove-if-not #'stringp rest))
        (dir user-emacs-directory ))
    (if rest (cond ( (equal str nil )
                    ;; Return string
                    (mapcar (lambda (str-arg)
                              (if ex (expand-file-name str-arg dir )
                                      (concat (abbreviate-file-name dir) str-arg ))) new-list))
                  ( (and (not (equal str t)) (< 1 (length new-list) ))
                    ;; Return list
                    (mapcar (lambda (str-arg)
                              (if ex (expand-file-name str-arg dir )
                                    (concat (abbreviate-file-name dir) str-arg ))) new-list))
                ( t (mapconcat (lambda (str-arg)
                      ;; Return string
                    (if ex (expand-file-name str-arg dir)
                            (concat (abbreviate-file-name dir) str-arg ))) new-list " ")))
            (expand-file-name user-emacs-directory))))

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.