Trying to set flycheck-clang-include-path without the need to include the full path of the project include directories using projectile, but I get errors... So this works:
((nil . (
(company-clang-arguments . (
"/home/user/Downloads/project/headers"
"/home/user/Downloads/project/source/mon"
))
(flycheck-clang-include-path . (
"/home/user/Downloads/project/headers"
"/home/user/Downloads/project/source/mon"
))
)))
But this does not:
((nil . (
(company-clang-arguments . (
(concat "-I" (projectile-project-root) "headers")
(concat "-I" (projectile-project-root) "source/mon")
))
(flycheck-clang-include-path . (
(concat (projectile-project-root) "headers")
(concat (projectile-project-root) "source/mon")
))
)))
The error that is reported:
flycheck-substitute-argument: Value ((concat (projectile-project-root) "headers")) of flycheck-clang-include-path for option "-I" is not a list of strings
One possibility is using an eval to evaluate the quoted forms in your dir-locals. This may be considered unsafe since anything could be evaluated in such a form.
((nil
(eval . (let ((root (projectile-project-root)))
(setq-local company-clang-arguments
(list (concat "-I" root "headers")
(concat "-I" root "source/mon")))
(setq-local flycheck-clang-include-path
(list (concat root "headers")
(concat root "source/mon")))))))
Related
While I've seen a lot of SO questions regarding archiving sub-trees, I use org-journal to create a daily file each day with a template (eg. 2018-09-14.org) which then I then record todos in a pre-templated structure for personal, work or what have you which go through various states till they are either finished DONE or cancelled KILL (I find this approach works for me since it also allows me visually to see in the agenda view how long a task has been hanging around since started).
I am trying to write an interactive function which:
processes a list of all my .org agenda files, and
if it detects all TODOs and DONE or KILL in the file (or there are none present),
prompts me y, n, skip to move the entire file to its whatever.org_archive
(starting to see slowdowns with agenda builds 5 months into using org-mode).
I'm assuming someone else already uses a similar approach ('cause emacs) but was wondering if anyone could point me at a similar function or approach that would be helpful for sussing this out. Googling and thrashing on the elisp has been unproductive so far.
=== One month later ===
Well, teaching myself some lisp has helped but am now at the point where I have the 3 independent functions working, but for some reason am getting an error on calling the final function.
However, I'm getting an error on line 28 with invalid function: on the call to rename-file-buffer-to-org-archive. If someone can see what the problem is, this solves my use case (and probably someone else's which is why I pasted it back here.).
(defun archive-done-org-journal-files ()
"Cycles all org files through checking function."
(interactive)
(save-excursion
(mapc 'check-org-file-finito (directory-files "~/Desktop/test_archives/" t ".org$"))
))
(defun check-org-file-finito (f)
"Checks TODO keyword items are DONE then archives."
(interactive)
(find-file f)
;; Shows open Todo items whether agenda or todo
(let (
(kwd-re
(cond (org-not-done-regexp)
(
(let ((kwd
(completing-read "Keyword (or KWD1|KWD2|...): "
(mapcar #'list org-todo-keywords-1))))
(concat "\\("
(mapconcat 'identity (org-split-string kwd "|") "\\|")
"\\)\\>")))
((<= (prefix-numeric-value) (length org-todo-keywords-1))
(regexp-quote (nth (1- (prefix-numeric-value))
org-todo-keywords-1)))
(t (user-error "Invalid prefix argument: %s")))))
(if (= (org-occur (concat "^" org-outline-regexp " *" kwd-re )) 0)
((rename-file-buffer-to-org-archive)
(kill-buffer (current-buffer)))
(kill-buffer (current-buffer))
)))
(defun rename-file-buffer-to-org-archive ()
"Renames current buffer and file it's visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name))
)
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name (concat (file-name-sans-extension filename) ".org_archive")))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(message "File '%s' successfully archived as '%s'."
name (file-name-nondirectory new-name)))))))
So, in the end, this is how I solved it. I'm sure there are optimizations and refactoring to be done here, but this definitely works and is reasonably modular if you need to figure it out. Just change the directory you use (mine is in Dropbox) for your org-files in the archive-done-org-journal-files and this should work for you. I highly recommend testing this on a test archive as per the ~/Desktop/test_archives/ directory as per the actual function just so you can make sure it works as advertised. YMMV. Hope it helps someone!
(defun archive-done-org-journal-files ()
"Cycles all org files through checking function."
(interactive)
(save-excursion
(mapc 'check-org-file-finito (directory-files "~/Desktop/test_archives/" t ".org$"))
))
(defun check-org-file-finito (f)
"Checks TODO keyword items are DONE then archives."
(interactive)
(find-file f)
;; Shows open Todo items whether agenda or todo
(let (
(kwd-re
(cond (org-not-done-regexp)
(
(let ((kwd
(completing-read "Keyword (or KWD1|KWD2|...): "
(mapcar #'list org-todo-keywords-1))))
(concat "\\("
(mapconcat 'identity (org-split-string kwd "|") "\\|")
"\\)\\>")))
((<= (prefix-numeric-value) (length org-todo-keywords-1))
(regexp-quote (nth (1- (prefix-numeric-value))
org-todo-keywords-1)))
(t (user-error "Invalid prefix argument: %s")))))
(if (= (org-occur (concat "^" org-outline-regexp " *" kwd-re )) 0)
(rename-file-buffer-to-org-archive)
(kill-buffer (current-buffer))
)))
(defun rename-file-buffer-to-org-archive ()
"Renames current buffer and file it's visiting."
(interactive)
(let ((name (buffer-name))
(filename (buffer-file-name))
)
(if (not (and filename (file-exists-p filename)))
(error "Buffer '%s' is not visiting a file!" name)
(let ((new-name (concat (file-name-sans-extension filename) ".org_archive")))
(if (get-buffer new-name)
(error "A buffer named '%s' already exists!" new-name)
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil)
(kill-buffer (current-buffer))
(message "File '%s' successfully archived as '%s'."
name (file-name-nondirectory new-name)))))))
Could anyone please give me a hand concatenating double quotes:
In this example, I'm writing a function to be used with Emacs on a Windows operating system. File names with spaces need to be enclosed in double-quotes.
The buffer-file-name is: c:/Documents and Settings/All Users/Desktop/foo.tex
I'm trying to use:
(setq pdf-file
(concat "\"" (car (split-string (buffer-file-name) "\\.tex")) ".pdf" "\""))
When I call (start-process "display" nil c:/SumatraPDF.exe pdf-file), the pdf viewer tries to open this instead:
c:\Documents and Settings\All Users\Desktop"c:\Documents and Settings\All Users\Desktop\foo.pdf"
EDIT: This is the function that I was trying to modify. As set forth in my answer below, the error was caused by my unwittingly having double-double-quoted the file name -- i.e., start-process treats a variable as being double-quoted, so there was never any need for me to concatenate another set of double quotes.
(defun latexmk ()
".latexmkrc contains the following entries:
$pdflatex = 'pdflatex -file-line-error -synctex=1 %O %S';
$pdf_mode = 1;
$recorder = 0;
$clean_ext = 'synctex.gz synctex.gz(busy) aux fdb_latexmk log';"
(interactive)
(setq tex-file (file-name-nondirectory buffer-file-name))
(setq base-file (car (split-string (file-name-nondirectory buffer-file-name) "\\.tex")))
(setq pdf-file (concat base-file ".pdf"))
(setq line (format "%d" (line-number-at-pos)))
(setq sumatra "C:/SumatraPDF/SumatraPDF.exe")
(setq tex-output (concat "*" (file-name-nondirectory buffer-file-name) "*") )
(setq latexmk "c:/texlive/2013/bin/win32/latexmk.exe")
(setq latexmkrc "c:/Documents and Settings/Administrator/Application Data/.emacs.d/.latexmkrc")
(if (buffer-modified-p)
(save-buffer))
(delete-other-windows)
(set-window-buffer (split-window-horizontally) (get-buffer-create tex-output))
(with-current-buffer tex-output (erase-buffer))
(start-process "tskill" nil "c:/WINDOWS/system32/tskill.exe" "SumatraPDF")
(set-process-sentinel
(start-process "deep-clean" nil latexmk "-C" "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "compile" tex-output latexmk "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "displayline" nil sumatra "-forward-search" tex-file line pdf-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "clean" nil latexmk "-c" "-r" latexmkrc tex-file)
(switch-to-buffer (get-file-buffer tex-file))
(if (get-buffer-process (get-buffer tex-output))
(process-kill-without-query (get-buffer-process (get-buffer tex-output))))
(kill-buffer tex-output)
(delete-other-windows)))))))))))
I'm guessing you want:
(replace-regexp-in-string
"\\.tex$"
".pdf"
"c:/Documents and Settings/All Users/Desktop/foo.tex")
(setq pdf-file (concat (file-name-sans-extension (buffer-file-name)) ".pdf"))
Also, if you need to quote an argument passed to a shell, use shell-quote-argument.
start-process treats a variable as if it were double-quoted. In essence, my variable ended up being double-double-quoted -- which is what was preventing me from using the absolute path to the file. So, in a nutshell, when using a variable with start-process, it need not be double-quoted.
Thank you to everyone who helped me to troubleshoot the issue -- greatly appreciated !
Here is the revised working function:
(defun latexmk ()
".latexmkrc contains the following entries:
$pdflatex = 'pdflatex -file-line-error -synctex=1 %O %S';
$pdf_mode = 1;
$recorder = 0;
$clean_ext = 'synctex.gz synctex.gz(busy) aux fdb_latexmk log';"
(interactive)
(setq tex-file (buffer-file-name))
(setq base-file (car (split-string (buffer-file-name) "\\.tex")))
(setq pdf-file (concat base-file ".pdf"))
(setq line (format "%d" (line-number-at-pos)))
(setq sumatra "c:/Program Files/SumatraPDF/SumatraPDF.exe")
(setq tex-output (concat "*" (file-name-nondirectory buffer-file-name) "*") )
(setq latexmk "c:/texlive/2013/bin/win32/latexmk.exe")
(setq latexmkrc "c:/Documents and Settings/Administrator/Application Data/.emacs.d/.latexmkrc")
(if (buffer-modified-p)
(save-buffer))
(delete-other-windows)
(set-window-buffer (split-window-horizontally) (get-buffer-create tex-output))
(with-current-buffer tex-output (erase-buffer))
(start-process "tskill" nil "c:/WINDOWS/system32/tskill.exe" "SumatraPDF")
(set-process-sentinel
(start-process "deep-clean" nil latexmk "-C" "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(set-process-sentinel
(start-process "compile" tex-output latexmk "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "displayline" nil sumatra "-forward-search" tex-file line pdf-file)
(start-process "clean" nil latexmk "-c" "-r" latexmkrc tex-file)
(switch-to-buffer (get-file-buffer tex-file))
(if (get-buffer-process (get-buffer tex-output))
(process-kill-without-query (get-buffer-process (get-buffer tex-output))))
(kill-buffer tex-output)
(delete-other-windows))))))))
I have the following setup in my .emacs ...
(defvar org-dir "/home/mash/read/org/")
And use it around such as ...
(setq org-directory org-dir)
(setq org-default-notes-file (concat org-dir "mash.org"))
Now I understand that you can specify a directory such as ...
(setq org-agenda-files '("/home/mash/read/org/"))
But how would I do this with the variable?
(setq org-agenda-files '(org-dir))
(setq org-agenda-files '(,(org-dir))
Any ideas as I would like to use it in my capture templates too ...
(setq org-capture-templates
'(("t" "Test" entry (file+headline (concat org-dir "test.org" "test")
"* %?")))
The '(foo bar) syntax is equivalent to writing (list 'foo 'bar). So you can set org-agenda-files like this:
(setq org-agenda-files (list org-dir))
Alternatively, you can replace the apostrophe ' with a backtick ` to create a list and then use comma to evaluate a part of that list
(setq org-capture-templates
`(("t" "Test" entry (file+headline ,(concat org-dir "test.org" "test")
"* %?")))
There are Tags as in #+AUTHOR or #+LATEX in org-mode - are they called tags? I'd like to define my own tag which calls a function to preprocess the data and then outputs it - if the export target is LaTeX.
My solution was defining an own language, qtree, for SRC blocks.
#+BEGIN_SRC qtree
[.CP [.TP [.NP [] [.N' [.N Syntax] []]] [.VP [] [.V' [.V sucks] []]]]]
#+END_SRC
And process it accordingly. I even added a qtree-mode with paredit.
And a landscape parameter if the trees grow big. https://github.com/Tass/emacs-starter-kit/blob/master/vendor/assorted/org-babel-qtree.el
(require 'org)
(defun org-babel-execute:qtree (body params)
"Reformat a block of lisp-edited tree to one tikz-qtree likes."
(let (( tree
(concat "\\begin{tikzpicture}
\\tikzset{every tree node/.style={align=center, anchor=north}}
\\Tree "
(replace-regexp-in-string
" \\_<\\w+\\_>" (lambda (x) (concat "\\\\\\\\" (substring x 1)))
(replace-regexp-in-string
(regexp-quote "]") " ]" ; qtree needs a space
; before every closing
; bracket.
(replace-regexp-in-string
(regexp-quote "[]") "[.{}]" body)) ; empty leaf
; nodes, see
; http://tex.stackexchange.com/questions/75915
) ; For
; http://tex.stackexchange.com/questions/75217
"\n\\end{tikzpicture}"
)))
(if (assoc :landscape params)
(concat "\\begin{landscape}\n" tree "\n\\end{landscape}")
tree)))
(setq org-babel-default-header-args:qtree '((:results . "latex") (:exports . "results")))
(add-to-list 'org-src-lang-modes '("qtree" . qtree))
(define-generic-mode
'qtree-mode ;; name of the mode to create
'("%") ;; comments start with '%'
'() ;; no keywords
'(("[." . 'font-lock-operator) ;; some operators
("]" . 'font-lock-operator))
'() ;; files for which to activate this mode
'(paredit-mode) ;; other functions to call
"A mode for qtree edits" ;; doc string for this mode
)
They seem to be called keywords for in-buffer settings no more. Whatever they're called, they don't seem to be user-definable.
What you want to do is extremely related to a common way of handling whereas to export with xelatex or pdflatex as described on Worg.
The relevant part would be :
;; Originally taken from Bruno Tavernier: http://thread.gmane.org/gmane.emacs.orgmode/31150/focus=31432
(defun my-auto-tex-cmd ()
(if (string-match "YOUR_TAG: value1" (buffer-string))
(do something))
(if (string-match "YOUR_TAG: value2" (buffer-string))
(do something else))
(add-hook 'org-export-latex-after-initial-vars-hook 'my-auto-tex-cmd)
I have an associated list of recently closed files of the form (buffer-name) . (buffer-file-name), like this:
(("04_-_Emacs.rst" . "/home/boris/pst/wordy/edu/HotKeyPoetry/04_-_Emacs.rst")
("lib_bk_files_dirs.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_files_dirs.py")
("lib_bk_text_related.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_text_related.py")
("lib_bk_media.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_media.py")
nil)
I want to get the value, for a given key:
(defun ergo-undo-close ()
(interactive)
(let ((mylist
;; let's get the keys (buffer names):
;; butlast for the last element of this alist is nil
(butlast (mapcar 'car recently-closed-buffers)))
baseName
fileName)
;; now let's choose the item to resurrect:
(setq baseName (ido-completing-read "Open this session closed buffer: " mylist))
(message baseName) ;; works fine
;; and find it's full path:
(setq fileName (assoc baseName mylist)) ;; <- **Edit**: recently-closed-buffers
;; should be here instead of mylist
(print fileName)
;; prints nil -- I expected it to print the pair:
;; (find-file (cdr fileName))
))
Edit:
Based on the answers below, here's what I'm using now:
(defun ergo-undo-close-buffer ()
"Opens some this-session closed buffer."
(interactive)
(let* ((mylist (delq nil (delete-dups (mapcar 'car recently-closed-buffers))))
(baseName (ido-completing-read "Open this session closed buffer: " mylist))
(fileName (cdr (assoc baseName recently-closed-buffers))))
(find-file fileName)))
You want to use (assoc baseName recently-closed-buffers) since mylist is not an alist. BTW, I'd also recommend you try and give a value to your variables right in the let rather than afterwards with a setq. For example:
(let* ((mylist
;; let's get the keys (buffer names):
;; butlast for the last element of this alist is nil
(butlast (mapcar 'car recently-closed-buffers)))
(baseName (ido-completing-read "Open this session closed buffer: " mylist))
(fileName (cdr (assoc baseName recently-closed-buffers))))
(print fileName))
(cdr (assoc "04_-_Emacs.rst"
'(("04_-_Emacs.rst" . "/home/boris/pst/wordy/edu/HotKeyPoetry/04_-_Emacs.rst")
("lib_bk_files_dirs.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_files_dirs.py")
("lib_bk_text_related.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_text_related.py")
("lib_bk_media.py" . "/home/boris/cmp/devs/bk_automates/bk_libs/lib_bk_media.py")
nil)))