* let*: Wrong type argument: stringp, nil @ 2021-09-24 14:52 Hongyi Zhao 2021-09-24 14:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-25 10:09 ` Stephen Berman 0 siblings, 2 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-24 14:52 UTC (permalink / raw) To: help-gnu-emacs According to the idea represented here [1], I wrote the following function to activate the python virtual environment automatically using the content of the ".python-version" file located in the project directory of the current opened python file: (defun pyvenv-autoload () (require 'projectile) (let* ((pdir (file-name-directory buffer-file-name)) (pfile (concat pdir ".python-version"))) (if (file-exists-p pfile) (pyvenv-workon (with-temp-buffer (insert-file-contents pfile) (nth 0 (split-string (buffer-string)))))))) (add-hook 'python-mode-hook 'pyvenv-autoload) It seems the corresponding python virtual environment can be activated automatically when I open the python file in Emacs. But when I try to evaluate the file, the following message will be triggered, and defeat the evaluate operation: let*: Wrong type argument: stringp, nil [1] https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-253902450 Any hints for fixing this problem? Regards -- Assoc. Prof. Hongyi Zhao <hongyi.zhao@gmail.com> Theory and Simulation of Materials Hebei Vocational University of Technology and Engineering No. 473, Quannan West Street, Xindu District, Xingtai, Hebei province ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-24 14:52 let*: Wrong type argument: stringp, nil Hongyi Zhao @ 2021-09-24 14:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-25 1:29 ` Hongyi Zhao 2021-09-25 10:09 ` Stephen Berman 1 sibling, 1 reply; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-24 14:57 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > let*: Wrong type argument: stringp, nil > > Any hints for fixing this problem? Indeed, inside a `let*', a variable is used in a function that expects a string. However either the variable is set to nil, or it isn't set at all. nil isn't a string so the function cannot operate, thus the error. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-24 14:57 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-25 1:29 ` Hongyi Zhao 2021-09-25 23:42 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-25 1:29 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Fri, Sep 24, 2021 at 10:58 PM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > Hongyi Zhao wrote: > > > let*: Wrong type argument: stringp, nil > > > > Any hints for fixing this problem? > > Indeed, inside a `let*', a variable is used in a function that > expects a string. However either the variable is set to nil, > or it isn't set at all. nil isn't a string so the function > cannot operate, thus the error. How to fix it or use a more robust method? Best, HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 1:29 ` Hongyi Zhao @ 2021-09-25 23:42 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-25 23:42 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: >> Indeed, inside a `let*', a variable is used in a function that >> expects a string. However either the variable is set to nil, >> or it isn't set at all. nil isn't a string so the function >> cannot operate, thus the error. > > How to fix it or use a more robust method? Send a string, not nil. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-24 14:52 let*: Wrong type argument: stringp, nil Hongyi Zhao 2021-09-24 14:57 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-25 10:09 ` Stephen Berman 2021-09-25 10:45 ` Hongyi Zhao 1 sibling, 1 reply; 35+ messages in thread From: Stephen Berman @ 2021-09-25 10:09 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs On Fri, 24 Sep 2021 22:52:45 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > According to the idea represented here [1], I wrote the following > function to activate the python virtual environment automatically > using the content of the ".python-version" file located in the project > directory of the current opened python file: > > (defun pyvenv-autoload () > (require 'projectile) > (let* ((pdir (file-name-directory buffer-file-name)) (pfile > (concat pdir ".python-version"))) > (if (file-exists-p pfile) > (pyvenv-workon (with-temp-buffer > (insert-file-contents pfile) > (nth 0 (split-string (buffer-string)))))))) > (add-hook 'python-mode-hook 'pyvenv-autoload) > > It seems the corresponding python virtual environment can be activated > automatically when I open the python file in Emacs. But when I try to > evaluate the file, the following message will be triggered, and defeat > the evaluate operation: > > let*: Wrong type argument: stringp, nil > > [1] https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-253902450 > > Any hints for fixing this problem? Evidently buffer-file-name is nil when the sexp `(file-name-directory buffer-file-name)' is evaluated, which indicates the current buffer when that function is called is not visiting a file (e.g., you get the same error when you evaluate `(file-name-directory buffer-file-name)' in *scratch*). Steve Berman ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 10:09 ` Stephen Berman @ 2021-09-25 10:45 ` Hongyi Zhao 2021-09-25 11:04 ` Stephen Berman 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-25 10:45 UTC (permalink / raw) To: Stephen Berman; +Cc: help-gnu-emacs On Sat, Sep 25, 2021 at 6:09 PM Stephen Berman <stephen.berman@gmx.net> wrote: > > On Fri, 24 Sep 2021 22:52:45 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > According to the idea represented here [1], I wrote the following > > function to activate the python virtual environment automatically > > using the content of the ".python-version" file located in the project > > directory of the current opened python file: > > > > (defun pyvenv-autoload () > > (require 'projectile) > > (let* ((pdir (file-name-directory buffer-file-name)) (pfile > > (concat pdir ".python-version"))) > > (if (file-exists-p pfile) > > (pyvenv-workon (with-temp-buffer > > (insert-file-contents pfile) > > (nth 0 (split-string (buffer-string)))))))) > > (add-hook 'python-mode-hook 'pyvenv-autoload) > > > > It seems the corresponding python virtual environment can be activated > > automatically when I open the python file in Emacs. But when I try to > > evaluate the file, the following message will be triggered, and defeat > > the evaluate operation: > > > > let*: Wrong type argument: stringp, nil > > > > [1] https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-253902450 > > > > Any hints for fixing this problem? > > Evidently buffer-file-name is nil when the sexp `(file-name-directory > buffer-file-name)' is evaluated, which indicates the current buffer when > that function is called is not visiting a file (e.g., you get the same > error when you evaluate `(file-name-directory buffer-file-name)' in > *scratch*). Thank you for pointing this out. Based on your above comment, I fixed the problem with the code below, and it does the trick: (defun pyvenv-autoload () (require 'projectile) (if (buffer-file-name) (let* ((pdir (file-name-directory buffer-file-name)) (pfile (concat pdir ".python-version"))) (if (file-exists-p pfile) (pyvenv-workon (with-temp-buffer (insert-file-contents pfile) (nth 0 (split-string (buffer-string))))))))) (add-hook 'python-mode-hook 'pyvenv-autoload) BTW, can I use `when' to write the above code? HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 10:45 ` Hongyi Zhao @ 2021-09-25 11:04 ` Stephen Berman 2021-09-25 13:49 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Stephen Berman @ 2021-09-25 11:04 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs On Sat, 25 Sep 2021 18:45:28 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > On Sat, Sep 25, 2021 at 6:09 PM Stephen Berman <stephen.berman@gmx.net> wrote: >> >> On Fri, 24 Sep 2021 22:52:45 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: >> >> > According to the idea represented here [1], I wrote the following >> > function to activate the python virtual environment automatically >> > using the content of the ".python-version" file located in the project >> > directory of the current opened python file: >> > >> > (defun pyvenv-autoload () >> > (require 'projectile) >> > (let* ((pdir (file-name-directory buffer-file-name)) (pfile >> > (concat pdir ".python-version"))) >> > (if (file-exists-p pfile) >> > (pyvenv-workon (with-temp-buffer >> > (insert-file-contents pfile) >> > (nth 0 (split-string (buffer-string)))))))) >> > (add-hook 'python-mode-hook 'pyvenv-autoload) >> > >> > It seems the corresponding python virtual environment can be activated >> > automatically when I open the python file in Emacs. But when I try to >> > evaluate the file, the following message will be triggered, and defeat >> > the evaluate operation: >> > >> > let*: Wrong type argument: stringp, nil >> > >> > [1] https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-253902450 >> > >> > Any hints for fixing this problem? >> >> Evidently buffer-file-name is nil when the sexp `(file-name-directory >> buffer-file-name)' is evaluated, which indicates the current buffer when >> that function is called is not visiting a file (e.g., you get the same >> error when you evaluate `(file-name-directory buffer-file-name)' in >> *scratch*). > > Thank you for pointing this out. Based on your above comment, I fixed > the problem with the code below, and it does the trick: > > (defun pyvenv-autoload () > (require 'projectile) > (if (buffer-file-name) > (let* ((pdir (file-name-directory buffer-file-name)) (pfile > (concat pdir ".python-version"))) > (if (file-exists-p pfile) > (pyvenv-workon (with-temp-buffer > (insert-file-contents pfile) > (nth 0 (split-string (buffer-string))))))))) > (add-hook 'python-mode-hook 'pyvenv-autoload) > > BTW, can I use `when' to write the above code? Certainly, indeed `when' is typically favored over `if' when there's no 'else' branch, as in the above code. On the other hand, since the point of the function is activate a virtual environment on visiting a Python file, you might want to add an 'else' branch that returns a suitable message when the current buffer is not visiting a file. Without that, in such a case the function just returns nil, so there's no indication the activation failed. BTW, your code would be easier to read if you began the second clause of the let* on a new line: (let* ((pdir (file-name-directory buffer-file-name)) (pfile (concat pdir ".python-version"))) Steve Berman ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 11:04 ` Stephen Berman @ 2021-09-25 13:49 ` Hongyi Zhao 2021-09-25 14:45 ` Stephen Berman 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-25 13:49 UTC (permalink / raw) To: Stephen Berman; +Cc: help-gnu-emacs On Sat, Sep 25, 2021 at 7:05 PM Stephen Berman <stephen.berman@gmx.net> wrote: > > On Sat, 25 Sep 2021 18:45:28 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > On Sat, Sep 25, 2021 at 6:09 PM Stephen Berman <stephen.berman@gmx.net> wrote: > >> > >> On Fri, 24 Sep 2021 22:52:45 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > >> > >> > According to the idea represented here [1], I wrote the following > >> > function to activate the python virtual environment automatically > >> > using the content of the ".python-version" file located in the project > >> > directory of the current opened python file: > >> > > >> > (defun pyvenv-autoload () > >> > (require 'projectile) > >> > (let* ((pdir (file-name-directory buffer-file-name)) (pfile > >> > (concat pdir ".python-version"))) > >> > (if (file-exists-p pfile) > >> > (pyvenv-workon (with-temp-buffer > >> > (insert-file-contents pfile) > >> > (nth 0 (split-string (buffer-string)))))))) > >> > (add-hook 'python-mode-hook 'pyvenv-autoload) > >> > > >> > It seems the corresponding python virtual environment can be activated > >> > automatically when I open the python file in Emacs. But when I try to > >> > evaluate the file, the following message will be triggered, and defeat > >> > the evaluate operation: > >> > > >> > let*: Wrong type argument: stringp, nil > >> > > >> > [1] https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-253902450 > >> > > >> > Any hints for fixing this problem? > >> > >> Evidently buffer-file-name is nil when the sexp `(file-name-directory > >> buffer-file-name)' is evaluated, which indicates the current buffer when > >> that function is called is not visiting a file (e.g., you get the same > >> error when you evaluate `(file-name-directory buffer-file-name)' in > >> *scratch*). > > > > Thank you for pointing this out. Based on your above comment, I fixed > > the problem with the code below, and it does the trick: > > > > (defun pyvenv-autoload () > > (require 'projectile) > > (if (buffer-file-name) > > (let* ((pdir (file-name-directory buffer-file-name)) (pfile > > (concat pdir ".python-version"))) > > (if (file-exists-p pfile) > > (pyvenv-workon (with-temp-buffer > > (insert-file-contents pfile) > > (nth 0 (split-string (buffer-string))))))))) > > (add-hook 'python-mode-hook 'pyvenv-autoload) > > > > BTW, can I use `when' to write the above code? > > Certainly, indeed `when' is typically favored over `if' when there's no > 'else' branch, as in the above code. But the actual demand exceeds the simple processing above, I mean, the real project maybe located under a specific folder with multiple level subdirectories. In this case, when I open a python file, the function should do the following: Search the current directory and its parent directories at all levels in turn. Once the ".python-version" file is found, activate the corresponding environment and exit the cycle; Otherwise, continue to search upwards until the certain top level directory, say, $HOME. Based on the above requirements and the code snippets given here [1-2], I finally figured out the following solution: ------- (defun parent-directory (dir) (unless (equal (getenv "HOME") dir) ;file-truename or directory-file-name (file-name-directory (directory-file-name dir)))) (defun find-file-in-heirarchy (current-dir fname) "Search for a file named FNAME upwards through the directory hierarchy, starting from CURRENT-DIR" (let ((file (concat current-dir fname)) (parent (parent-directory (expand-file-name current-dir)))) (if (file-exists-p file) file (when parent (find-file-in-heirarchy parent fname))))) (defun try/pyvenv-workon () (when (buffer-file-name) (let ((file (find-file-in-heirarchy (buffer-file-name) ".python-version"))) (when (file-exists-p file) (pyvenv-workon (with-temp-buffer (insert-file-contents file) (nth 0 (split-string (buffer-string))))))))) (add-hook 'python-mode-hook 'try/pyvenv-workon) ------- It works like a charm. But any suggestions/enhancements/comments will be greatly appreciated. [1] https://stackoverflow.com/a/14096693 (*) [2] http://sodaware.sdf.org/notes/emacs-lisp-find-file-upwards/ * Indicated that this is my main reference source code. > On the other hand, since the point > of the function is activate a virtual environment on visiting a Python > file, you might want to add an 'else' branch that returns a suitable > message when the current buffer is not visiting a file. Without that, > in such a case the function just returns nil, so there's no indication > the activation failed. Good advice. > BTW, your code would be easier to read if you began the second clause of > the let* on a new line: > > (let* ((pdir (file-name-directory buffer-file-name)) > (pfile (concat pdir ".python-version"))) Good advice, again. HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 13:49 ` Hongyi Zhao @ 2021-09-25 14:45 ` Stephen Berman 2021-09-25 15:03 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Stephen Berman @ 2021-09-25 14:45 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs On Sat, 25 Sep 2021 21:49:38 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: [...] > But the actual demand exceeds the simple processing above, I mean, the > real project maybe located under a specific folder with multiple level > subdirectories. In this case, when I open a python file, the function > should do the following: Search the current directory and its parent > directories at all levels in turn. Once the ".python-version" file is > found, activate the corresponding environment and exit the cycle; > Otherwise, continue to search upwards until the certain top level > directory, say, $HOME. Based on the above requirements and the code > snippets given here [1-2], I finally figured out the following > solution: > > ------- > (defun parent-directory (dir) > (unless (equal (getenv "HOME") dir) > ;file-truename or directory-file-name > (file-name-directory (directory-file-name dir)))) > > > (defun find-file-in-heirarchy (current-dir fname) > "Search for a file named FNAME upwards through the directory > hierarchy, starting from CURRENT-DIR" > (let ((file (concat current-dir fname)) > (parent (parent-directory (expand-file-name current-dir)))) > (if (file-exists-p file) > file > (when parent > (find-file-in-heirarchy parent fname))))) > > > (defun try/pyvenv-workon () > (when (buffer-file-name) > (let ((file (find-file-in-heirarchy (buffer-file-name) > ".python-version"))) > (when (file-exists-p file) > (pyvenv-workon (with-temp-buffer > (insert-file-contents file) > (nth 0 (split-string > (buffer-string))))))))) > > (add-hook 'python-mode-hook 'try/pyvenv-workon) > ------- > > It works like a charm. But any suggestions/enhancements/comments will > be greatly appreciated. > > [1] https://stackoverflow.com/a/14096693 (*) > [2] http://sodaware.sdf.org/notes/emacs-lisp-find-file-upwards/ > > * Indicated that this is my main reference source code. Doesn't using the built-in Emacs function `locate-dominating-file', as mentioned in the stackoverflow thread, work just as well as `find-file-in-heirarchy'? Steve Berman ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 14:45 ` Stephen Berman @ 2021-09-25 15:03 ` Hongyi Zhao 2021-09-28 3:08 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-25 15:03 UTC (permalink / raw) To: Stephen Berman; +Cc: help-gnu-emacs On Sat, Sep 25, 2021 at 10:45 PM Stephen Berman <stephen.berman@gmx.net> wrote: > > On Sat, 25 Sep 2021 21:49:38 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > [...] > > But the actual demand exceeds the simple processing above, I mean, the > > real project maybe located under a specific folder with multiple level > > subdirectories. In this case, when I open a python file, the function > > should do the following: Search the current directory and its parent > > directories at all levels in turn. Once the ".python-version" file is > > found, activate the corresponding environment and exit the cycle; > > Otherwise, continue to search upwards until the certain top level > > directory, say, $HOME. Based on the above requirements and the code > > snippets given here [1-2], I finally figured out the following > > solution: > > > > ------- > > (defun parent-directory (dir) > > (unless (equal (getenv "HOME") dir) > > ;file-truename or directory-file-name > > (file-name-directory (directory-file-name dir)))) > > > > > > (defun find-file-in-heirarchy (current-dir fname) > > "Search for a file named FNAME upwards through the directory > > hierarchy, starting from CURRENT-DIR" > > (let ((file (concat current-dir fname)) > > (parent (parent-directory (expand-file-name current-dir)))) > > (if (file-exists-p file) > > file > > (when parent > > (find-file-in-heirarchy parent fname))))) > > > > > > (defun try/pyvenv-workon () > > (when (buffer-file-name) > > (let ((file (find-file-in-heirarchy (buffer-file-name) > > ".python-version"))) > > (when (file-exists-p file) > > (pyvenv-workon (with-temp-buffer > > (insert-file-contents file) > > (nth 0 (split-string > > (buffer-string))))))))) > > > > (add-hook 'python-mode-hook 'try/pyvenv-workon) > > ------- > > > > It works like a charm. But any suggestions/enhancements/comments will > > be greatly appreciated. > > > > [1] https://stackoverflow.com/a/14096693 (*) > > [2] http://sodaware.sdf.org/notes/emacs-lisp-find-file-upwards/ > > > > * Indicated that this is my main reference source code. > > Doesn't using the built-in Emacs function `locate-dominating-file', as > mentioned in the stackoverflow thread, work just as well as > `find-file-in-heirarchy'? According to my current test, it can indeed work very well. But I don't know if there are edge cases which this solution doesn't treated correctly. The built-in Emacs function `locate-dominating-file' relies on several other predefined functions, and It has been tested and iterated a lot. So, maybe it's more robust. HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-25 15:03 ` Hongyi Zhao @ 2021-09-28 3:08 ` Hongyi Zhao 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 8:02 ` Yuri Khan 0 siblings, 2 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-28 3:08 UTC (permalink / raw) To: Stephen Berman; +Cc: help-gnu-emacs On Sat, Sep 25, 2021 at 11:03 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Sat, Sep 25, 2021 at 10:45 PM Stephen Berman <stephen.berman@gmx.net> wrote: > > > > On Sat, 25 Sep 2021 21:49:38 +0800 Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > [...] > > > But the actual demand exceeds the simple processing above, I mean, the > > > real project maybe located under a specific folder with multiple level > > > subdirectories. In this case, when I open a python file, the function > > > should do the following: Search the current directory and its parent > > > directories at all levels in turn. Once the ".python-version" file is > > > found, activate the corresponding environment and exit the cycle; > > > Otherwise, continue to search upwards until the certain top level > > > directory, say, $HOME. Based on the above requirements and the code > > > snippets given here [1-2], I finally figured out the following > > > solution: > > > > > > ------- > > > (defun parent-directory (dir) > > > (unless (equal (getenv "HOME") dir) > > > ;file-truename or directory-file-name > > > (file-name-directory (directory-file-name dir)))) > > > > > > > > > (defun find-file-in-heirarchy (current-dir fname) > > > "Search for a file named FNAME upwards through the directory > > > hierarchy, starting from CURRENT-DIR" > > > (let ((file (concat current-dir fname)) > > > (parent (parent-directory (expand-file-name current-dir)))) > > > (if (file-exists-p file) > > > file > > > (when parent > > > (find-file-in-heirarchy parent fname))))) > > > > > > > > > (defun try/pyvenv-workon () > > > (when (buffer-file-name) > > > (let ((file (find-file-in-heirarchy (buffer-file-name) > > > ".python-version"))) > > > (when (file-exists-p file) > > > (pyvenv-workon (with-temp-buffer > > > (insert-file-contents file) > > > (nth 0 (split-string > > > (buffer-string))))))))) > > > > > > (add-hook 'python-mode-hook 'try/pyvenv-workon) > > > ------- > > > > > > It works like a charm. But any suggestions/enhancements/comments will > > > be greatly appreciated. > > > > > > [1] https://stackoverflow.com/a/14096693 (*) > > > [2] http://sodaware.sdf.org/notes/emacs-lisp-find-file-upwards/ > > > > > > * Indicated that this is my main reference source code. > > > > Doesn't using the built-in Emacs function `locate-dominating-file', as > > mentioned in the stackoverflow thread, work just as well as > > `find-file-in-heirarchy'? > > According to my current test, it can indeed work very well. But I > don't know if there are edge cases which this solution doesn't treated > correctly. The built-in Emacs function `locate-dominating-file' relies > on several other predefined functions, and It has been tested and > iterated a lot. So, maybe it's more robust. Now I'm trying another test code snippet based on the idea posted here [1]: (defun desperately-pyvenv-workon() "Traveling up the path, find a `.python-version' and activate the corresponding virtualenv." (interactive) (with-temp-buffer (unless (equal(getenv "HOME") default-directory) (while (not (file-exists-p ".python-version")) (cd "..") )) (when(file-exists-p ".python-version") (message(expand-file-name ".python-version"))))) (desperately-pyvenv-workon) [1] https://emacs.stackexchange.com/a/7477 But when I test the above code in scratch buffer, it seems to be stuck in an endless loop and running there all the time. Any hints for this problem? HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 3:08 ` Hongyi Zhao @ 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 3:24 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 5:25 ` Hongyi Zhao 2021-09-28 8:02 ` Yuri Khan 1 sibling, 2 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 3:21 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > Now I'm trying another test code snippet based on the idea > posted here [1]: > > (defun desperately-pyvenv-workon() > "Traveling up the path, find a `.python-version' and activate the > corresponding virtualenv." > (interactive) > (with-temp-buffer > (unless (equal(getenv "HOME") default-directory) > (while (not (file-exists-p ".python-version")) > (cd "..") > )) > (when(file-exists-p ".python-version") > (message(expand-file-name ".python-version"))))) > > (desperately-pyvenv-workon) > > [1] https://emacs.stackexchange.com/a/7477 > > But when I test the above code in scratch buffer, it seems to be stuck > in an endless loop and running there all the time. Eval this (cd "..") enough times and it alternates between "/" and "/../" indefinitely, maybe that's what happens? (But I don't know why, or what it tries to say with "/../" which should be equivalent to "/" ... in the shell, cd from / does not lead to /../ but will stay in /) Also, if you are just looking for a file, isn't there better ways to do that? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 3:24 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 5:25 ` Hongyi Zhao 1 sibling, 0 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 3:24 UTC (permalink / raw) To: help-gnu-emacs > Also, if you are just looking for a file, isn't there better > ways to do that? https://www.emacswiki.org/emacs/LocateFilesAnywhere -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 3:24 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 5:25 ` Hongyi Zhao 2021-09-28 7:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-28 5:25 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Tue, Sep 28, 2021 at 11:22 AM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > Hongyi Zhao wrote: > > > Now I'm trying another test code snippet based on the idea > > posted here [1]: > > > > (defun desperately-pyvenv-workon() > > "Traveling up the path, find a `.python-version' and activate the > > corresponding virtualenv." > > (interactive) > > (with-temp-buffer > > (unless (equal(getenv "HOME") default-directory) > > (while (not (file-exists-p ".python-version")) > > (cd "..") > > )) > > (when(file-exists-p ".python-version") > > (message(expand-file-name ".python-version"))))) > > > > (desperately-pyvenv-workon) > > > > [1] https://emacs.stackexchange.com/a/7477 > > > > But when I test the above code in scratch buffer, it seems to be stuck > > in an endless loop and running there all the time. > > Eval this > > (cd "..") > > enough times and it alternates between "/" and "/../" > indefinitely, maybe that's what happens? > > (But I don't know why, or what it tries to say with "/../" > which should be equivalent to "/" ... in the shell, cd from / > does not lead to /../ but will stay in /) They are really equivalent: werner@X10DAi-00:/$ realpath -e /../ / werner@X10DAi-00:/$ realpath -e / / ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 5:25 ` Hongyi Zhao @ 2021-09-28 7:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 7:20 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: >> Eval this >> >> (cd "..") >> >> enough times and it alternates between "/" and "/../" >> indefinitely, maybe that's what happens? >> >> (But I don't know why, or what it tries to say with "/../" >> which should be equivalent to "/" ... in the shell, cd from / >> does not lead to /../ but will stay in /) > > They are really equivalent: > > werner@X10DAi-00:/$ realpath -e /../ > / > werner@X10DAi-00:/$ realpath -e / > / Yeah, looks like a bug this. Harmless and technically not incorrect perhaps but suboptimal/confusing, especially the alternating back and forth. (cd "..") at / should be a no-op that returns "/" IMO. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 3:08 ` Hongyi Zhao 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-28 8:02 ` Yuri Khan 2021-09-28 8:24 ` Hongyi Zhao 2021-09-29 1:43 ` Hongyi Zhao 1 sibling, 2 replies; 35+ messages in thread From: Yuri Khan @ 2021-09-28 8:02 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Stephen Berman On Tue, 28 Sept 2021 at 10:08, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > Now I'm trying another test code snippet based on the idea posted here [1]: > > (while (not (file-exists-p ".python-version")) > (cd "..") > )) > > But when I test the above code in scratch buffer, it seems to be stuck > in an endless loop and running there all the time. Any hints for this > problem? You’re not handling the case here that you reached the root directory without finding a .python-version file. You will really get better results if you use locate-dominating-file. If you’re trying to learn, learn by reading that function. As a bonus, it does not mess with the buffer’s default directory. ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 8:02 ` Yuri Khan @ 2021-09-28 8:24 ` Hongyi Zhao 2021-09-29 1:43 ` Hongyi Zhao 1 sibling, 0 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-28 8:24 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Stephen Berman On Tue, Sep 28, 2021 at 4:02 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > On Tue, 28 Sept 2021 at 10:08, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > Now I'm trying another test code snippet based on the idea posted here [1]: > > > > (while (not (file-exists-p ".python-version")) > > (cd "..") > > )) > > > > But when I test the above code in scratch buffer, it seems to be stuck > > in an endless loop and running there all the time. Any hints for this > > problem? > > You’re not handling the case here that you reached the root directory > without finding a .python-version file. > > You will really get better results if you use locate-dominating-file. > If you’re trying to learn, learn by reading that function. As a bonus, > it does not mess with the buffer’s default directory. Thanks for the tip! I will give up further attempts on this path. If available, I will first try to use and learn by reading the source code of the Emacs built-in functions. Best, HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-28 8:02 ` Yuri Khan 2021-09-28 8:24 ` Hongyi Zhao @ 2021-09-29 1:43 ` Hongyi Zhao 2021-09-29 2:03 ` Hongyi Zhao 2021-09-29 4:35 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 2 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 1:43 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Stephen Berman On Tue, Sep 28, 2021 at 4:02 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > On Tue, 28 Sept 2021 at 10:08, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > Now I'm trying another test code snippet based on the idea posted here [1]: > > > > (while (not (file-exists-p ".python-version")) > > (cd "..") > > )) > > > > But when I test the above code in scratch buffer, it seems to be stuck > > in an endless loop and running there all the time. Any hints for this > > problem? > > You’re not handling the case here that you reached the root directory > without finding a .python-version file. > > You will really get better results if you use locate-dominating-file. > If you’re trying to learn, learn by reading that function. As a bonus, > it does not mess with the buffer’s default directory. I work out the following code snippets using locate-dominating-file, and it works as expected: (defun try/pyvenv-workon () (when (locate-dominating-file (buffer-file-name) ".python-version") ;https://emacs.stackexchange.com/questions/9474/let-statement-throws-error-on-assigning-a-form-to-a-variable (let ((file (concat (locate-dominating-file (buffer-file-name) ".python-version") ".python-version"))) (pyvenv-workon (with-temp-buffer (insert-file-contents file) (nth 0 (split-string (buffer-string)))))))) BTW, should I use `let' or `let*' here? HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 1:43 ` Hongyi Zhao @ 2021-09-29 2:03 ` Hongyi Zhao 2021-09-29 3:02 ` Hongyi Zhao 2021-09-29 4:35 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 2:03 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Stephen Berman On Wed, Sep 29, 2021 at 9:43 AM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Tue, Sep 28, 2021 at 4:02 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > > > On Tue, 28 Sept 2021 at 10:08, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > > Now I'm trying another test code snippet based on the idea posted here [1]: > > > > > > (while (not (file-exists-p ".python-version")) > > > (cd "..") > > > )) > > > > > > But when I test the above code in scratch buffer, it seems to be stuck > > > in an endless loop and running there all the time. Any hints for this > > > problem? > > > > You’re not handling the case here that you reached the root directory > > without finding a .python-version file. > > > > You will really get better results if you use locate-dominating-file. > > If you’re trying to learn, learn by reading that function. As a bonus, > > it does not mess with the buffer’s default directory. > > I work out the following code snippets using locate-dominating-file, > and it works as expected: > > (defun try/pyvenv-workon () > (when (locate-dominating-file (buffer-file-name) ".python-version") The following form should be used here: (when (and (buffer-file-name) (locate-dominating-file (buffer-file-name) ".python-version")) > ;https://emacs.stackexchange.com/questions/9474/let-statement-throws-error-on-assigning-a-form-to-a-variable > (let ((file (concat (locate-dominating-file (buffer-file-name) > ".python-version") ".python-version"))) > (pyvenv-workon (with-temp-buffer > (insert-file-contents file) > (nth 0 (split-string (buffer-string)))))))) > > > BTW, should I use `let' or `let*' here? > > HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 2:03 ` Hongyi Zhao @ 2021-09-29 3:02 ` Hongyi Zhao 2021-09-29 3:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 3:02 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Stephen Berman On Wed, Sep 29, 2021 at 10:03 AM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Wed, Sep 29, 2021 at 9:43 AM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > On Tue, Sep 28, 2021 at 4:02 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > > > > > On Tue, 28 Sept 2021 at 10:08, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > > > > Now I'm trying another test code snippet based on the idea posted here [1]: > > > > > > > > (while (not (file-exists-p ".python-version")) > > > > (cd "..") > > > > )) > > > > > > > > But when I test the above code in scratch buffer, it seems to be stuck > > > > in an endless loop and running there all the time. Any hints for this > > > > problem? > > > > > > You’re not handling the case here that you reached the root directory > > > without finding a .python-version file. > > > > > > You will really get better results if you use locate-dominating-file. > > > If you’re trying to learn, learn by reading that function. As a bonus, > > > it does not mess with the buffer’s default directory. > > > > I work out the following code snippets using locate-dominating-file, > > and it works as expected: > > > > (defun try/pyvenv-workon () > > (when (locate-dominating-file (buffer-file-name) ".python-version") > > The following form should be used here: > > (when (and (buffer-file-name) (locate-dominating-file > (buffer-file-name) ".python-version")) > > > ;https://emacs.stackexchange.com/questions/9474/let-statement-throws-error-on-assigning-a-form-to-a-variable > > (let ((file (concat (locate-dominating-file (buffer-file-name) > > ".python-version") ".python-version"))) > > (pyvenv-workon (with-temp-buffer > > (insert-file-contents file) > > (nth 0 (split-string (buffer-string)))))))) The complete code for this purpose is as following now: (defun try/pyvenv-workon () (when (and (buffer-file-name) (locate-dominating-file (buffer-file-name) ".python-version")) (let ((file (concat (locate-dominating-file (buffer-file-name) ".python-version") ".python-version"))) (pyvenv-workon (with-temp-buffer (insert-file-contents file) (nth 0 (split-string (buffer-string)))))))) But I wonder if I can solve this problem by using `locate-dominating-file' only once? HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 3:02 ` Hongyi Zhao @ 2021-09-29 3:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 6:15 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 3:57 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > (defun try/pyvenv-workon () > (when (and (buffer-file-name) > (locate-dominating-file (buffer-file-name) ".python-version")) > (let ((file (concat (locate-dominating-file (buffer-file-name) > ".python-version") ".python-version"))) > (pyvenv-workon > (with-temp-buffer > (insert-file-contents file) > (nth 0 (split-string (buffer-string)))))))) Use `let' so you don't have to hard-code the same data three times. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 3:57 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 6:15 ` Hongyi Zhao 2021-09-29 6:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 6:15 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Wed, Sep 29, 2021 at 11:58 AM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > Hongyi Zhao wrote: > > > (defun try/pyvenv-workon () > > (when (and (buffer-file-name) > > (locate-dominating-file (buffer-file-name) ".python-version")) > > (let ((file (concat (locate-dominating-file (buffer-file-name) > > ".python-version") ".python-version"))) > > (pyvenv-workon > > (with-temp-buffer > > (insert-file-contents file) > > (nth 0 (split-string (buffer-string)))))))) > > Use `let' so you don't have to hard-code the same data three > times. The code I’ve modified looks like this: (defun try/pyvenv-workon () (when (buffer-file-name) (let ((file (concat (locate-dominating-file (buffer-file-name) ".python-version") ".python-version"))) (when (file-exists-p file) (pyvenv-workon (with-temp-buffer (insert-file-contents file) (nth 0 (split-string (buffer-string))))))))) Any further improvement tips? HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 6:15 ` Hongyi Zhao @ 2021-09-29 6:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 7:37 ` Hongyi Zhao 2021-09-29 9:14 ` Yuri Khan 0 siblings, 2 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 6:29 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > The code I’ve modified looks like this: > > (defun try/pyvenv-workon () > (when (buffer-file-name) > (let ((file (concat (locate-dominating-file (buffer-file-name) > ".python-version") ".python-version"))) > (when (file-exists-p file) > (pyvenv-workon > (with-temp-buffer > (insert-file-contents file) > (nth 0 (split-string (buffer-string))))))))) > > Any further improvement tips? concat -> format ".python-version" hardcoded twice nth 0 -> car -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 6:29 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 7:37 ` Hongyi Zhao 2021-09-29 8:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 9:14 ` Yuri Khan 1 sibling, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 7:37 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Wed, Sep 29, 2021 at 2:29 PM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > concat -> format > > ".python-version" hardcoded twice > > nth 0 -> car Thanks again. Then, is there room for further improvement in the following code? (defun try/pyvenv-workon () (when (buffer-file-name) (let* ((python-version ".python-version") (venvdir (locate-dominating-file (buffer-file-name) python-version))) (when venvdir (pyvenv-workon (with-temp-buffer (insert-file-contents (format "%s%s" venvdir python-version)) (car (split-string (buffer-string))))))))) HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 7:37 ` Hongyi Zhao @ 2021-09-29 8:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 9:02 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 8:21 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > Thanks again. Then, is there room for further improvement in > the following code? > > (defun try/pyvenv-workon () > (when (buffer-file-name) > (let* ((python-version ".python-version") > (venvdir (locate-dominating-file (buffer-file-name) > python-version))) > (when venvdir > (pyvenv-workon > (with-temp-buffer > (insert-file-contents (format "%s%s" venvdir python-version)) > (car (split-string (buffer-string))))))))) Looks good to me. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 8:21 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 9:02 ` Hongyi Zhao 0 siblings, 0 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 9:02 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Wed, Sep 29, 2021 at 4:21 PM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > Looks good to me. Thank you for your comment and help. In order to be more in line with the actual situation, I replaced the variable name `venvdir' with `project-dir': (defun try/pyvenv-workon () (when (buffer-file-name) (let* ((python-version ".python-version") (project-dir (locate-dominating-file (buffer-file-name) python-version))) (when project-dir (pyvenv-workon (with-temp-buffer (insert-file-contents (format "%s%s" project-dir python-version)) (car (split-string (buffer-string))))))))) HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 6:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 7:37 ` Hongyi Zhao @ 2021-09-29 9:14 ` Yuri Khan 2021-09-29 10:29 ` Hongyi Zhao 2021-09-30 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 2 replies; 35+ messages in thread From: Yuri Khan @ 2021-09-29 9:14 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Wed, 29 Sept 2021 at 13:29, Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > (let ((file (concat (locate-dominating-file (buffer-file-name) > > ".python-version") ".python-version"))) > concat -> format Why use either, when you have a perfectly good expand-file-name? ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 9:14 ` Yuri Khan @ 2021-09-29 10:29 ` Hongyi Zhao 2021-09-29 12:29 ` Yuri Khan 2021-09-30 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 10:29 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Emanuel Berg On Wed, Sep 29, 2021 at 5:14 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > On Wed, 29 Sept 2021 at 13:29, Emanuel Berg via Users list for the GNU > Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > > (let ((file (concat (locate-dominating-file (buffer-file-name) > > > ".python-version") ".python-version"))) > > > concat -> format > > Why use either, when you have a perfectly good expand-file-name? Good advice, so change to the following: (defun try/pyvenv-workon () (when (buffer-file-name) (let* ((python-version ".python-version") (project-dir (locate-dominating-file (buffer-file-name) python-version))) (when project-dir (pyvenv-workon (with-temp-buffer (insert-file-contents (expand-file-name python-version)) (car (split-string (buffer-string))))))))) HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 10:29 ` Hongyi Zhao @ 2021-09-29 12:29 ` Yuri Khan 2021-09-29 12:49 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Yuri Khan @ 2021-09-29 12:29 UTC (permalink / raw) To: Hongyi Zhao; +Cc: help-gnu-emacs, Emanuel Berg On Wed, 29 Sept 2021 at 17:29, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > (defun try/pyvenv-workon () > (when (buffer-file-name) > (let* ((python-version ".python-version") > (project-dir (locate-dominating-file (buffer-file-name) > python-version))) > (when project-dir > (pyvenv-workon > (with-temp-buffer > (insert-file-contents (expand-file-name python-version)) You probably wanted (expand-file-name python-version project-dir) here. > (car (split-string (buffer-string))))))))) ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 12:29 ` Yuri Khan @ 2021-09-29 12:49 ` Hongyi Zhao 2021-10-08 3:36 ` Hongyi Zhao 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 12:49 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Emanuel Berg On Wed, Sep 29, 2021 at 8:30 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > On Wed, 29 Sept 2021 at 17:29, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > (defun try/pyvenv-workon () > > (when (buffer-file-name) > > (let* ((python-version ".python-version") > > (project-dir (locate-dominating-file (buffer-file-name) > > python-version))) > > (when project-dir > > (pyvenv-workon > > (with-temp-buffer > > (insert-file-contents (expand-file-name python-version)) > > You probably wanted (expand-file-name python-version project-dir) here. Good catch! You're absolutely right. Thanks again for your help. > > > (car (split-string (buffer-string))))))))) ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 12:49 ` Hongyi Zhao @ 2021-10-08 3:36 ` Hongyi Zhao 2021-10-10 14:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 1 reply; 35+ messages in thread From: Hongyi Zhao @ 2021-10-08 3:36 UTC (permalink / raw) To: Yuri Khan; +Cc: help-gnu-emacs, Emanuel Berg On Wed, Sep 29, 2021 at 8:49 PM Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > On Wed, Sep 29, 2021 at 8:30 PM Yuri Khan <yuri.v.khan@gmail.com> wrote: > > > > On Wed, 29 Sept 2021 at 17:29, Hongyi Zhao <hongyi.zhao@gmail.com> wrote: > > > > > (defun try/pyvenv-workon () > > > (when (buffer-file-name) > > > (let* ((python-version ".python-version") > > > (project-dir (locate-dominating-file (buffer-file-name) > > > python-version))) > > > (when project-dir > > > (pyvenv-workon > > > (with-temp-buffer > > > (insert-file-contents (expand-file-name python-version)) > > > > You probably wanted (expand-file-name python-version project-dir) here. > > Good catch! You're absolutely right. Thanks again for your help. > > > > > > (car (split-string (buffer-string))))))))) Here is another implementation based on s and f given by pyenv-mode-auto [1]: (require 's) (require 'f) (require 'pyenv-mode) (defun pyenv-mode-auto-hook () "Automatically activates pyenv version if .python-version file exists." (f-traverse-upwards (lambda (path) (let ((pyenv-version-path (f-expand ".python-version" path))) (if (f-exists? pyenv-version-path) (progn (pyenv-mode-set (car (s-lines (s-trim (f-read-text pyenv-version-path 'utf-8))))) t)))))) (add-hook 'find-file-hook 'pyenv-mode-auto-hook) (provide 'pyenv-mode-auto) [1] https://github.com/ssbb/pyenv-mode-auto/blob/347b94cd5ad22e33cc41be661c102d4548767858/pyenv-mode-auto.el#L35-L51 HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-10-08 3:36 ` Hongyi Zhao @ 2021-10-10 14:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 0 siblings, 0 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-10-10 14:05 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > Here is another implementation based on s and f given by > pyenv-mode-auto [...] > > (require 's) > (require 'f) What is that, string and file modules? It usually doesn't look like that in Lisp. > (f-exists? [...] This reminds me of some other Lisp dialect where you'd have an exclamation mark last if the function hade side-effects. So maybe a question mark last is their way of doing our `-p' (or vice versa depending on who was first). While I don't want to make too big a thing of it, conventions like these are probably better not to mix. (Ours look better, also. Less disruptive.) -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 9:14 ` Yuri Khan 2021-09-29 10:29 ` Hongyi Zhao @ 2021-09-30 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 1 sibling, 0 replies; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-30 3:38 UTC (permalink / raw) To: help-gnu-emacs Yuri Khan wrote: >>> (let ((file (concat (locate-dominating-file (buffer-file-name) >>> ".python-version") ".python-version"))) >> >> concat -> format > > Why use either, when you have a perfectly good > expand-file-name? Right, just looked at the syntax :$ I do that all the time BTW ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 1:43 ` Hongyi Zhao 2021-09-29 2:03 ` Hongyi Zhao @ 2021-09-29 4:35 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 6:17 ` Hongyi Zhao 1 sibling, 1 reply; 35+ messages in thread From: Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 4:35 UTC (permalink / raw) To: help-gnu-emacs Hongyi Zhao wrote: > (defun try/pyvenv-workon () > (when (locate-dominating-file (buffer-file-name) ".python-version") > ;https://emacs.stackexchange.com/questions/9474/let-statement-throws-error-on-assigning-a-form-to-a-variable > (let ((file (concat (locate-dominating-file (buffer-file-name) > ".python-version") ".python-version"))) > (pyvenv-workon (with-temp-buffer > (insert-file-contents file) > (nth 0 (split-string (buffer-string)))))))) > > BTW, should I use `let' or `let*' here? `let*' always works, `let' works when there is no references to previous bindings in any binding... So if it works and you have let, you have done the right thing! In theory, because of the independence of the individual bindings with let, it can be used to compute in parallel - but I don't think that actually happens - an urban legend ... In your code you only have "file" so while both would work, let* is unnecessary ... -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: let*: Wrong type argument: stringp, nil 2021-09-29 4:35 ` Emanuel Berg via Users list for the GNU Emacs text editor @ 2021-09-29 6:17 ` Hongyi Zhao 0 siblings, 0 replies; 35+ messages in thread From: Hongyi Zhao @ 2021-09-29 6:17 UTC (permalink / raw) To: Emanuel Berg, help-gnu-emacs On Wed, Sep 29, 2021 at 12:35 PM Emanuel Berg via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> wrote: > > Hongyi Zhao wrote: > > > (defun try/pyvenv-workon () > > (when (locate-dominating-file (buffer-file-name) ".python-version") > > ;https://emacs.stackexchange.com/questions/9474/let-statement-throws-error-on-assigning-a-form-to-a-variable > > (let ((file (concat (locate-dominating-file (buffer-file-name) > > ".python-version") ".python-version"))) > > (pyvenv-workon (with-temp-buffer > > (insert-file-contents file) > > (nth 0 (split-string (buffer-string)))))))) > > > > BTW, should I use `let' or `let*' here? > > `let*' always works, `let' works when there is no references > to previous bindings in any binding... > > So if it works and you have let, you have done the > right thing! > > In theory, because of the independence of the individual > bindings with let, it can be used to compute in parallel - but > I don't think that actually happens - an urban legend ... > > In your code you only have "file" so while both would work, > let* is unnecessary ... Wonderful explanation. Got it. Thank you very much again. HZ ^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2021-10-10 14:05 UTC | newest] Thread overview: 35+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-09-24 14:52 let*: Wrong type argument: stringp, nil Hongyi Zhao 2021-09-24 14:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-25 1:29 ` Hongyi Zhao 2021-09-25 23:42 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-25 10:09 ` Stephen Berman 2021-09-25 10:45 ` Hongyi Zhao 2021-09-25 11:04 ` Stephen Berman 2021-09-25 13:49 ` Hongyi Zhao 2021-09-25 14:45 ` Stephen Berman 2021-09-25 15:03 ` Hongyi Zhao 2021-09-28 3:08 ` Hongyi Zhao 2021-09-28 3:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 3:24 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 5:25 ` Hongyi Zhao 2021-09-28 7:20 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-28 8:02 ` Yuri Khan 2021-09-28 8:24 ` Hongyi Zhao 2021-09-29 1:43 ` Hongyi Zhao 2021-09-29 2:03 ` Hongyi Zhao 2021-09-29 3:02 ` Hongyi Zhao 2021-09-29 3:57 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 6:15 ` Hongyi Zhao 2021-09-29 6:29 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 7:37 ` Hongyi Zhao 2021-09-29 8:21 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 9:02 ` Hongyi Zhao 2021-09-29 9:14 ` Yuri Khan 2021-09-29 10:29 ` Hongyi Zhao 2021-09-29 12:29 ` Yuri Khan 2021-09-29 12:49 ` Hongyi Zhao 2021-10-08 3:36 ` Hongyi Zhao 2021-10-10 14:05 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-30 3:38 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 4:35 ` Emanuel Berg via Users list for the GNU Emacs text editor 2021-09-29 6:17 ` Hongyi Zhao
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.