I have several bash scripts that output SQL. 99% of the time I want emacs to edit it in sql-mode. I inserted this into my .emacs file:
(add-to-list 'auto-mode-alist '("\\.sql\\.sh\\'" . sql-mode))
I get the right mode if I open a non-existing file like 'foobar.sql.sh' within emacs. However, if I open an existing file that has #!/bin/bash as the first line, I get shell-script-mode. How do I change it so that I get sql-mode?
If you check your interpreter-mode-alist variable, you'll find an entry like ("r?bash2?" . sh-mode) or ("bash" . sh-mode) depending on which version of emacs you're running. This setting takes precedence over magic-mode-alist and auto-mode-alist.
I suggest removing that entry from interpreter-mode-alist, getting rid of the new entry you added to auto-mode-alist, and adding two new entries to magic-mode-alist instead:
(add-to-list 'magic-mode-alist '("r?bash2?" . sh-mode))
(add-to-list 'magic-mode-alist
'((lambda ()
(string-match "\\.sql\\.sh$" (buffer-file-name))) . sql-mode))
Be sure to add them in this order so the second one is in front of the first one in the resulting list (and yes, there are other ways of doing this but I'm showing it this way for clarity). The second entry, which will be tried first, checks the buffer name to see if it matches a .sql.sh suffix and sets sql-mode if so. If that match fails, the other entry checks the beginning of the buffer for the same pattern interpreter-mode-alist was looking for and sets sh-mode if it matches.
Related
Ok so i did something very stupid (copying a file and renaming it '.') since I thought it would just copy it as .uniprot_sprot.fasta.gz.icloud.
cp /path/.uniprot_sprot.fasta.gz.icloud .
and now I don't know how to remove it from current directory as it would be removing '.' itself.
What can I do?
This doesn't work. It says: No such file or directory
rm .uniprot_sprot.fasta.gz.icloud
On the other hand:
ls -a
gives this:
.
..
uniprot_sprot.fasta.gz.icloud
You have not copied a file and renamed it . (at any rate if you're running a sane *nix). Instead you have copied the file to the current directory with the name of the original file. (If you pass a directory to cp as the destination, files will be placed in that directory. . is the current directory, so this is all that has happened.) If you want to remove it you can just rm uniprot_sprot.fasta.gx.iscloud or explicitly rm ./uniprot_sprot.fasta.gx.iscloud. What you have tried to do is to remove a file whose name starts with ., which is a different thing.
Edit: I was unaware when I wrote this, but this is in fact simply down to . existing as a real, regular hardlink. At syscall level you can create a file whose name contains anything except / and \x00 (yep, including \n), assuming your filesystem allows it. However, the links . and .. are already present and thus unavailable as a file name. #thatotherguy links to the kernel source for the rmdir syscall, showing that in modern Linux at least it is the kernel itself which ultimately prevents you from deleting . and ...
Note that in bash, . at the beginning of a line by itself means source.
See this question on unix.se and its linked dupe for more information on the filename problem.
I am new to to guile and scheme and what I am trying to do right now is take a scheme file (file.scm) and load it up into a variable so I will be able to parse it, and I am having trouble finding how to do this anywhere.
What I have right now is
(define var (load "file.scm")) ; loads file scheme
but I am unsure how to start reading the lines.
load parses and runs the scheme code in a file. If you just want to read a file, use open-input-file.
(define file (open-input-file "file address here"))
(display (read-line file))
If you just want to read an entire file as a string, there's a function for that in the textual-ports module. You'd use it something like:
(define contents (call-with-input-file "file.txt" get-string-all))
(You can use call-with-input-file and with-input-from-file to avoid having to manually open and close a file port, which is handy)
I use project-root to setup root directory of the project as:
(setq project-roots
`(("Git Project"
:root-contains-files (".gitignore"))))
Then I go into my git project directory (e.g ~/.emacs.d), and press M-x ag-project-files and enter some search string. It shows the files which contains the string. But when I push enter key on top of the file (in order to jump into that file), it shows error message like:
Find this error in (default File: lisp/ag.el): ~/.emacs.d/
I don't know how this error come out? It is all right when I use emacs in Linux, but no good in Mac. Have you ever met this problem?
I ran into this same problem using projectile-ag. It turned out that setting the "--nogroup" parameter for ag was causing this break (but only on macOS). To work around this I just set ag-arguments to not include the "--nogroup" param:
(setq ag-arguments (list "--smart-case" "--column"))
I tried the instructions - I am using Firefox on Lubuntu (Openbox). But I get the error
"Firefox doesn't know how to open this address, because the protocol (org-protocol) isn't associated with any program".
How should I fix this?
The following steps for setting up org-protocol work with Ubuntu 16.04 (Xenial Xerus) and presumably later versions. Org-mode is assumed to have already been set-up (and installed using apt-get install org-mode or via the ELPA repository).
Set-up
Add .desktop file
Create and save a file called org-protocol.desktop to ~/.local/share/applications containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Then run:
$ update-desktop-database ~/.local/share/applications/
This step makes Firefox aware that "org-protocol" is a valid scheme-handler or protocol (by updating ~/.local/share/applications/mimeinfo.cache), and causes Firefox to prompt for a program to use when opening these kinds of links.
Add config settings to ~/.emacs.d/init.el (or ~/.emacs) file
Have the following settings in your Emacs configuration file:
(server-start)
(require 'org-protocol)
Also add some template definitions to the configuration file, for example:
(setq org-protocol-default-template-key "l")
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "/path/to/notes.org" "Tasks")
"* TODO %?\n %i\n %a")
("l" "Link" entry (file+olp "/path/to/notes.org" "Web Links")
"* %a\n %?\n %i")
("j" "Journal" entry (file+datetree "/path/to/journal.org")
"* %?\nEntered on %U\n %i\n %a")))
Now run Emacs.
Create your notes.org file
Assuming you use the capture templates defined in step 2, you will need to prepare a notes.org file at the location you specified in step 2. You must create this file -- if it is not created along with the headlines specified in step 2, org-mode will just give a warning when you try to capture web-pages. So, given the capture templates from step 2, notes.org should contain the following:
* Tasks
* Web Links
Add bookmarklet(s) to Firefox
Save bookmark to toolbar containing something like the following as the location:
javascript:location.href='org-protocol://capture?template=l&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&body='+encodeURIComponent(window.getSelection())
If you are using an older version of org-mode, you may need to use the following instead:
javascript:location.href='org-protocol://capture://l/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Notice the 'l' (lowercase L) in the above URL -- this is what chooses the capture template (automatically) -- it is the key one would normally have to press when capturing with org-mode via C-c c.
When you click on this bookmarklet, Firefox will ask what program to use to handle the "org-protocol" protocol. You can simply choose the default program that appears ("org-protocol").
Using it
(Optionally) select some text on a webpage you're viewing in Firefox. When you click on the bookmarklet, the link and selected text will be placed in the Emacs capture buffer. Go to Emacs, modify the capture buffer as desired, and press C-c C-c to save it.
Add protocol handler
Create file ~/.local/share/applications/org-protocol.desktop containing:
[Desktop Entry]
Name=org-protocol
Exec=emacsclient %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;
Note: Each line's key must be capitalized exactly as displayed, or it will be an invalid .desktop file.
Then update ~/.local/share/applications/mimeinfo.cache by running:
On GNOME:
update-desktop-database ~/.local/share/applications/
On KDE:
kbuildsycoca4
Configure Emacs
Init file
Add to your Emacs init file:
(server-start)
(require 'org-protocol)
Capture template
You'll probably want to add a capture template something like this:
("w" "Web site"
entry
(file+olp "/path/to/inbox.org" "Web")
"* %c :website:\n%U %?%:initial")
Note: Using %:initial instead of %i seems to handle multi-line content better.
This will result in a capture like this:
\* [[http://orgmode.org/worg/org-contrib/org-protocol.html][org-protocol.el – Intercept calls from emacsclient to trigger custom actions]] :website:
[2015-09-29 Tue 11:09] About org-protocol.el
org-protocol.el is based on code and ideas from org-annotation-helper.el and org-browser-url.el.
Configure Firefox
Expose protocol-handler
On some versions of Firefox, it may be necessary to add this setting. You may skip this step and come back to it if you get an error saying that Firefox doesn't know how to handle org-protocol links.
Open about:config and create a new boolean value named network.protocol-handler.expose.org-protocol and set it to true.
Note: If you do skip this step, and you do encounter the error, Firefox may replace all open tabs in the window with the error message, making it difficult or impossible to recover those tabs. It's best to use a new window with a throwaway tab to test this setup until you know it's working.
Make bookmarklet
Make a bookmarklet with the location:
javascript:location.href='org-protocol://capture://w/'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
Note: The w in the URL chooses the corresponding capture template. You can leave it out if you want to be prompted for the template.
When you click on this bookmarklet for the first time, Firefox will ask what program to use to handle the org-protocol protocol. If you are using Ubuntu 12.04 (Precise Pangolin), you must add the /usr/bin/emacsclient program, and choose it. With Ubuntu 12.10 (Quantal Quetzal) or later, you can simply choose the default program that appears (org-protocol).
You can select text in the page when you capture and it will be copied into the template, or you can just capture the page title and URL.
Tridactyl
If you're using Tridactyl, you can map key sequences something like this:
bind cc js location.href='org-protocol://capture://w/'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)+'/'+encodeURIComponent(content.document.getSelection())
You might also want to add one for the `store-link` sub-protocol, like:
bind cl js location.href='org-protocol://store-link://'+encodeURIComponent(content.location.href)+'/'+encodeURIComponent(content.document.title)
Capture script
You may want to use this script to capture input from a terminal, either as an argument or piped in:
#!/bin/bash
if [[ $# ]]
then
data="$#"
else
data=$(cat)
fi
if [[ -z $data ]]
then
exit 1
fi
encoded=$(python -c "import sys, urllib; print urllib.quote(' '.join(sys.argv[1:]), safe='')" "${data[#]}")
# "link" and "title" are not used, but seem to be necessary to get
# $encoded to be captured
emacsclient "org-protocol://capture://link/title/$encoded"
Then you can capture input from the shell like this:
tail /var/log/syslog | org-capture
org-capture "I can capture from a terminal!"
These instructions are more up-to-date than the ones in Mark's answer.
I am using TinyScheme (actually Script-Fu in GIMP), and cannot find a good way to open a file and append a line of text to it.
I am trying to log some info to the file for debugging, and transcript-on doesn't seem to be implemented...
Right now I am scraping along by reading the entire file (one character at a time!), concatenating that into a string, concatenating my text to the end of that, then writing it all out to the file again.
There must be a better way!
It's going to be something like
(open-file "myfile" (file-options append))
You want to look up the file-options function.
Update
Here's the guile version:
(open-file "myfilename.dat" "a")
Just had the same exact problem in GIMP and decided to use open-input-output-file. My solution is something like this:
(let* ((out (open-input-output-file "file.txt") ))
(display "hello world" out)
(newline out)
(close-output-port out))
Went through the TinyScheme source and checked that this function actually calls fopen with "a+". The file is open for reading and writing. For our purposes we only want to write, so just ignore reading.
I am writing a Script-Fu to write the values of gimp-selection-bounds to a file.