I would like emacs to mark files that are generated as read-only when they're opened. The part of the puzzle that I'm missing is how to check if a file "exists". I currently have the following:
;; ;; get file extension ;; (defun get-ext (file-name) (car (cdr (split-string file-name "\\.")))) ;; ;; get the base name of the file ;; (defun base-name (file-name) (car (split-string file-name "\\."))) ;; ;; if an 'lzz' file exists for this header, mark it as read only ;; (defun mark-read-only () (if (string= (get-ext (cur-file)) "h") (if ( ??file-exists??? (concat (base-name (cur-file)) ".lzz") ) (toggle-read-only))))
What can I use for "???file-exists???"?
Once I find this, I'll add "mark-read-only" to the appropriate hook (which I think is the find-file-hook).
BACKGROUND
We use lzz as a code generator to simplify our C/C++ development process. Briefly, lzz takes a single input file (which looks very like C/C++) and generates header and source files as appropriate.
By default, lzz includes #line directives so that the debugger points to the original source and not the generated source, however, to reduce compilation dependencies we normally disable these directives in header files. The result is that when debugging templates or inline functions, the debugger normally points to the generated header file and not the original source file.
This is not a big deal, however, recently I've found that when debugging I'll make a quick modification to the displayed file and then I'll rebuild. Of course this normally means that the change I made disappears because the file I edited is generated and so the changes are "blown away" during the library rebuild.
SOLUTION
Thanks to everyone for their help and comments. A special thanks to cobbal for pointing out the correct function to use.
Here's the resulting code (with updates based on the other comments here too):
(defun cur-file () "Return the filename (without directory) of the current buffer" (file-name-nondirectory (buffer-file-name (current-buffer))) ) (defun mark-generated-as-read-only () "Mark generated source files as read only. Mark generated files (lzz or gz) read only to avoid accidental updates." (if (or (string= (file-name-extension (cur-file)) "h") (string= (file-name-extension (cur-file)) "cpp")) (cond ( (file-exists-p (concat (file-name-sans-extension (cur-file)) ".lzz")) (toggle-read-only)) ( (file-exists-p (concat (file-name-sans-extension (cur-file)) ".gz") ) (toggle-read-only)) ) ) )
To find a file in Emacs, you use the C-x C-f ( find-file ) command.
By default, Common Lisp is lexically scoped, that is, every variable is lexically scoped except for special variables. By default, Emacs Lisp files are dynamically scoped, that is, every variable is dynamically scoped. The my-test. el is a lexically scoped file because of the first line.
Emacs Lisp is a dialect of the Lisp programming language used as a scripting language by Emacs (a text editor family most commonly associated with GNU Emacs and XEmacs). It is used for implementing most of the editing functionality built into Emacs, the remainder being written in C, as is the Lisp interpreter.
Gnu emacs is written almost entirely in Common Lisp! Unfortunately, this version of Common Lisp is so incomplete that it won't be sufficient for programming in our class. Instead, you can run and use lisp within emacs.
try file-exists-p
"Return t if file filename exists (whether or not you can read it.)".
Note that it's not spesific to files and works for directories too.
Depending on what you need, you might want file-readable-p
instead of file-exists-p
.
Apropos will only get you so far. Icicles provides apropos completion and progressive completion which let you find help easily for command, function, variable, etc. names that match subparts in an arbitrary order (is it file-exists-p
or exists-file-p
?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With