Emacs lisp: evaluating list of strings - string

I am new to elisp but I am trying to spice up my .emacs a little.
I am trying to define some paths, but having problems with creating a list of paths (and setting the list for YaSnippet more specifically).
When I evaluate the list I get a list of the symbol name (and not the symbol values as yassnippet want).
I got the code working but have feeling that there is a better way to do this?
Here is the working code:
;; some paths
(setq my-snippets-path "~/.emacs.d/snippets")
(setq default-snippets-path "~/.emacs.d/site-lisp/yasnippet/snippets")
;; set the yas/root-directory to a list of the paths
(setq yas/root-directory `(,my-snippets-path ,default-snippets-path))
;; load the directories
(mapc 'yas/load-directory yas/root-directory)

If you evaluate a list of strings, the result depends on the value of the list items. The best way to test that is to launch the ielm repl (M-x ielm), and enter:
ELISP> '("abc" "def" "ghi")
("abc" "def" "ghi")
The quoted list of string evaluates to the list value. If you store the value of the list in a variable, and then evaluate the variable, ELisp will complain that the function abc is unknown.
ELISP> (setq my-list '("abc" "def" "ghi"))
("abc" "def" "ghi")
ELISP> (eval my-list)
*** Eval error *** Invalid function: "abc"
For the yasnippet directory configuration, you should just set yas-snippet-dir instead, e.g.
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
(setq yas-snippet-dirs
'("~/.emacs.d/snippets" ;; personal snippets
"/path/to/yasnippet/snippets" ;; the default collection
"/path/to/other/snippets" ;; add any other folder with a snippet collection
))
(yas-global-mode 1)
Edit:
The use of yas/root-directory has been deprecated. From the documentation of yasnippet.el
`yas-snippet-dirs'
The directory where user-created snippets are to be
stored. Can also be a list of directories. In that case,
when used for bulk (re)loading of snippets (at startup or
via `yas-reload-all'), directories appearing earlier in
the list shadow other dir's snippets. Also, the first
directory is taken as the default for storing the user's
new snippets.
The deprecated `yas/root-directory' aliases this variable
for backward-compatibility.

I think you want
(setq yas/root-directory (list my-snippets-path default-snippets-path))

Related

Why are arguments to an enclosing function not captured by closures in Common Lisp?

test.lisp:
(defvar test
#'(lambda (var1)
#'(lambda (var2)
`((var1 . ,var1)
(var2 . ,var2)))))
(defvar var1 'wrong)
(defvar var2 'wrong)
And in the REPL:
$ clisp -q -i test.lisp
;; Loading file test.lisp ...
;; Loaded file test.lisp
[1]> (funcall (funcall test 'right) 'right)
((VAR1 . WRONG) (VAR2 . RIGHT))
I thought that common lisp was supposed to be lexically scoped these days, so why is the value of var1 not captured by the inner lambda in test? How can I make sure it is captured?
This is visible when using an interpreter.
Let's look at a compiler first:
? (load "/tmp/test.lisp")
#P"/private/tmp/test.lisp"
? (funcall (funcall test 'right) 'right)
((VAR1 . RIGHT) (VAR2 . RIGHT))
First the functions are getting compiled. The compiler assumes lexical binding. Then DEFVAR declares the variables VAR1 and VAR2 to be special (-> not lexical). In the executed code then, the code is still using lexical binding.
You were using an Interpreter:
First the functions are loaded. Nothing gets compiled. Then DEFVAR declares VAR1 and VAR2 as special.
In the executed code then, the Interpreter is using dynamic binding - like you declared it. The Interpreter looks at the variables at runtime and sees that they are declared to be special.
Difference:
The compiler has generated the machine code before the special declaration. Thus at runtime it uses lexical binding.
The interpreter looks at runtime at the existing declarations.
Style
If you want to avoid dynamic binding, don't declare variables to be special.
defvar (and defparameter) declare the variable to be special (dynamic). Give your special variables *earmuffs* to prevent surprises about whether a binding is lexical or dynamic.

Fast directory clean-up with Perl

I have a need to clean-up directory with millions of log files on my webserver. And I've found this great article on how to do this. There is, however, a couple interesting things in that one-liner, which I am interested in.
Here's the Perl code I am interested in:
for(<*>){((stat)[9]<(unlink))}
Runned with perl -e 'code'.
So, here are my questions:
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
the stat and unlink functions expect at least one argument, I assume... But where is it?
why the result of calling (stat)[9] is compared to the result of calling (unlink)? And what does it results in?
Sorry, I am a no-perl-ish guy, thus I do not understand all those Perl abbreviations. That's why I am asking this question.
Thanks!
That one liner takes many shortcuts:
The <*> is a special case of the diamond operator. You can't access an iterator object, like in other languages. Here, it calls the glob function. In list context it returns a list from all the results (which are either lines of a file, or, as in your case, contents of a diretory. The return value of that is passed to for which iterates over a list and aliases the values in $_. $_ is the "default variable" for many functions…
Which brings us here. Many core functions default to $_ with no argument. So do unlink and stat.
(stat)[9] means execute stat in list context and select the 10th result (indices start at zero, this is the modify time). (compare that to an array access like $foo[9]).
The code
for(<*>){((stat)[9]<(unlink))}
is equivalent to:
for my $file (<*>) {
my $mtime = (stat($file))[9];
$mtime < unlink($file);
}
<*> can also be replaced with glob "*" which might be more readable.
The code will delete all files in the current directory. It will not delete directories.
Note that the last statement in the loop is completely redundant. If use warnings is in effect, it will give the warning:
Useless use of numeric lt (<) in void context
For this code to make sense, I would expect a comparison that actually matters, like comparing $mtime to some time to know which logs are old, e.g.:
if ($mtime < $oldtime) {
unlink $file or die "Cannot unlink $file: $!";
}
Note also that it might be prudent to check for failure when deleting files.
the for(<*>) construction - I assume it iterates through the files in the current directory. But where does it store the iterator?
for-loops can be used to iterate over arrays/lists, so if <*> produces a list, then your code is just a run of the mill for loop. As it turns out <*> is another way to spell glob(), which is sort of like a regex for retrieving file names, and glob() returns a list in list context--which is the context a for loop provides. See: http://perldoc.perl.org/functions/glob.html.
Note that the single quotes keep the shell from expanding the *, which would prevent perl from ever seeing it.

Lisp Scheme using (string-set!) Error Encountered

I am new to (Lisp) scheme programming and have been following the tutorial. Everything went well until I use string-set!
String-set! is use to replace the character at index. An example of what I did below:
Welcome to Racket v5.1.3.
> (define greeting "Hello; Hello!")
> (string-set! greeting 1 #\a)
string-set!: expects type <mutable string> as 1st argument, given: "Hello; Hello!"; other arguments were: 1 #\a
=== context ===
/usr/share/racket/collects/racket/private/misc.rkt:85:7
> greeting
"Hello; Hello!"
>
When (string-set! greeting 1 #\a) executed, it should replace the first 'e' to 'a' according to the tutorial. The output should be:
> greeting
"Hallo; Hello!"
But instead I am getting the error string-set!: expects type <mutable string> as 1st argument.
Am I doing it the wrong way?
As per the Racket documentation:
A string can be mutable or immutable. When an immutable string is provided to a procedure like string-set!, the exn:fail:contract exception is raised. String constants generated by the default reader (see Reading Strings) are immutable, and they are interned in read-syntax mode.
You can use string-copy to make a copy of a string, and this always returns a mutable string.
(define greeting (string-copy "Hello; Hello!"))
Your code is not suppose to work according to the R5RS or R6RS. It clearly states:
(define (g) "***")
(string-set! (g) 0 #\?) ===> error
It might be an error in your tutorial. You need to make the string mutable:
(define greeting (string-copy "Hello; Hello!"))
(string-set! greeting 1 #\a)
greeting ; ==> "Hallo; Hello!"
BTW: When you start Racket from command line or DrRacket in a windowed environment your are not expected to write Scheme, but a dialect that has diverged from the standard called racket. Most of Scheme will work though, but not set-car! or set-cdr!.
I advice you to use a Scheme standard according your tutorial. To use racket to run a Scheme standard from command line, you start either plt-r5rs or plt-r6rs. In DrRacket you can use choose language in the bottom left. Choose "Other > Legacy language R5RS" or select The racket language and start your definitions windows with:
#!r6rs
(import (rnrs))
DrRacket has a debugger so I recommend it. I googled your line and if you are following Teach Yourself Scheme in Fixnum Days, it conforms to the R5RS standard.
If you rather want to learn racket I recommend Realm of racket (2013) since you make games, which are fun. There is also a free book called How to design programs (2003).

My Lisp interpreter doesn't recognize defgrammar?

I'm new to Lisp, so I'm guessing I'm missing something simple here. I found some code online that I wanted to play with, and it uses the defgrammar macro. When I write it into my code file, copied exactly from the web to start with, save, and load, it says (with file name omitted):
;; Loading file ...
*** - EVAL: undefined function DEFGRAMMAR
I'm guessing there's some variable I have to flip, like for printing circular lists, or some add-on or something I have to install, but I don't really know what I'm looking for. Any suggestions?
By the way, I'm using GNU CLisp 2.49.
The code I'm trying to use is:
(load "rdp")
(use-package "COM.INFORMATIMAGO.RDP")
(defgrammar binary-tree
:terminals ((label "[^(),][^(),]*"))
:start tree
:rules ((--> tree
(opt node)
:action (if (null $1)
(make-empty-binary-tree)
$1)) ; it's identity, but make-empty-binary-tree
; could be defined otherwise.
(--> node
label (opt children)
:action (make-binary-tree :label (read-from-string (second $1))
:left (first $2) :right (second $2)))
(--> children
"(" tree "," tree ")"
:action (list $2 $4))))
(defun binary-tree-from-string (string)
(parse-binary-tree string))
Looking at it, I'm guessing I need "rdp"?
What's the code you want to play with, could you paste it here? defgrammar is not a built-in function. You should find the definition of defgrammar function. Load it first then re-evaluate your example.

Emacs Searching

I have a convoluted search request. Lets say that I am searching for an URI pattern. I do know the scheme and the authority. Lets say http://mycompany.com.
After this URI pattern, ideally most of the URI in my search domain have two path variable.
/Context/Resource. Although it could have more. But it will always have a context.
I would like to find the distinct set of first path variable. I do not mind about the second and subsequent path variable.So if I have this.Lets use a qname is myc.
myc:/context1/resource1
myc:/context1/resource2
myc:/context2/resource1
myc:/context3/resource1
myc:/context4/resource8
myc:/context1/resource12
I will have to get context1..4. Thank You for your time.
If I understand you correctly,
(require 'cl)
(remove-duplicates
(loop while (re-search-forward "myc:/\\(.*?\\)/" nil t)
collect (match-string-no-properties 1))
:test #'string=)
Emacs supports regex searches which are normally bound to C-M-s.
The Emacs manual has a nice section about regular expressions in Emacs.
There is also M-x regexp-builder to help you build the search string with real-time feedback.

Resources