Showing posts with label emacs. Show all posts
Showing posts with label emacs. Show all posts

2018-01-23

Make a copy of saved files to another directory


For various reasons I needed to sync files between one folder to another as soon as a certain file was saved in the first folder. I was wondering if Emacs could do this for me, and of course it could :)

Basically, what I am using below is Emacs' `after-save-hook' together with a list of regular expressions matching files to be "synced" and the target folder to copy the files to. Each time I save a file, the list of regexps will be checked and if there is a match, the file will also be copied to the defined target directory. Neat!

It works very well so I thought of sharing it in this way. Also, it was a long time since I wrote a blog post here... :)

Put the following code in your .emacs or init.el file and then customize after-save-file-sync-regexps.

Enjoy!

;; The Code

(defcustom after-save-file-sync-regexps nil
  "A list of cons cells consisting of two strings. The `car' of
each cons cell is the regular expression matching the file(s)
that should be copied, and the `cdr' is the target directory."
  :group 'files
  :type '(repeat (cons string string)))

(defcustom after-save-file-sync-ask-if-overwrite nil
  "Ask the user before overwriting the destination file.
When set to a non-`nil' value, the user will be asked. When
`nil', the file will be copied without asking"
  :group 'files
  :type 'boolean)

(defun after-save-file-sync ()
  "Sync the current file if it matches one of the regexps.

This function will match each regexp in
`after-save-file-sync-regexps' against the current file name. If
there is a match, the current file will be copied to the
configured target directory.

If the file already exist target directory, the option
`after-save-file-sync-ask-if-overwrite' will control if the file
should be written automatically or if the user should be
presented with a question.

In theory, the same file can be copied to multiple target
directories, by configuring multiple regexps that match the same
file."

  (dolist (file-regexp after-save-file-sync-regexps)
    (when (string-match (car file-regexp) (buffer-file-name))
      (let ((directory (file-name-as-directory (cdr file-regexp))))
        (copy-file (buffer-file-name) directory (if after-save-file-sync-ask-if-overwrite 1 t))
        (message "Copied file to %s" directory)))))

(add-hook 'after-save-hook 'after-save-file-sync)

;; The End



2016-09-12

barebones.el - the most basic .emacs file I use

Today I decided to write a little bit of documentation for my most basic version of .emacs or init.el that I use. It gets me up to 80% or so of full productivity for basic text editing on a new installation.

It can be found here:

https://github.com/mathiasdahl/dotemacs (download the barebones.el file)

Perhaps someone else will find it useful, as it is or as a simple start for their own Emacs customizations.

Enjoy!

2015-12-22

Evil Mode hack for a colorful mode line

Intro

After trying out Spacemacs for about a week (and failing - too much old configuration to "convert") I am trying out Evil Mode by itself. It goes forward, slowly, step by step.

One thing I have been a bit annoyed with was how the different states are visualized. Being a Evil/Vim newbie I want to see, clearly, in which state/mode I am in.

Today I decided to do something about it and here is how my Emacs looks now:

Normal state


Insert state


Emacs state




How it was done

I could not find any good entry points for customizing the mode line with respect to the Evil Mode states, but I found the function (evil-generate-mode-line-tag) that generates the part of the mode line that comes from Evil Mode. I simply made a copy of it and changed it to add also a face attribute to the mode line, and let the face be different depending on the mode.

The code

Copy the code below and save it in a file called my-evil-hacks.el.

After this you need to make sure to load this file after you have loaded Evil mode for the first time. One way to achieve this is to put the following snippet in your .emacs or init.el file:
(with-eval-after-load "evil"
  (load "my-evil-hacks"))
Enjoy!

2015-08-21

Something I should have done a long time ago...

This is something I should have done a long time ago, to make window creation and manipulation easier in Emacs:

(global-set-key (kbd "C-1") 'delete-other-windows)
(global-set-key (kbd "C-2") 'split-window-below)
(global-set-key (kbd "C-3") 'split-window-right)
(global-set-key (kbd "C-0") 'delete-window)

It gives the window manipulating commands I use the most nicer key bindings; just by keeping the Ctrl key pressed and typing away (crazily) on the keys 2 and 3 you can create master pieces of window configurations :)

I could do this since I realized I seldom or never use these shortcuts to enter a numeric argument. If I need to, I can use a slightly longer key sequence like C-u 1 or M-1 which I have kept (for now...).

Perhaps this post will inspire someone else to do the same.

2015-07-18

Evaluating elisp expressions from a web page with a custom URI scheme

Intro


Very boring title, eh? :) Well, this is kinda neat...

Some of you might already know that you can install a custom URI scheme handler in most operating system. Today I did an experiment with that together with Emacs and it turned out quite nicely. I did
this in Windows but it should work in GNU/Linux and OS X as well.


So, what is an URI scheme?


Briefly explained, the URI scheme is the "http" part in URLs that we all use everyday. Other examples are "ftp" and "file". The most common ones are handled by your web browser but you can also have another program on your computer handle a certain URI scheme. You can register your own URI schemes as well and in this post we will experiment with a new URI scheme that we name "emacs", for evaluating expressions/executing commands in Emacs.


A warning


If you decide to do this, you should be very careful, since it could be a big security risk. Either you let the warning from your web browser always be there to warn you (it can be supressed easily, for a
better user experience) or you register a secret URI scheme (like "myverysecretemacsurischeme") that no one else knows about. Otherwise, bad people can do very nasty things with your computer...

Okay, with that aside, let's go!


Step 1 - Registering a new URI scheme


In Windows you register a new URI scheme in the Windows registry (where else...). Basically you have to create the following key/folder structure under the HKEY_CLASSES_ROOT hive:

<name of URI scheme handler>
  shell
    open
      command

Lastly, the "command" key's Default value (right hand side) should have the path to the program handling the request, and %1 should be there to, to send in the parameters from the URL to the program.

If you dare, you can save the following snippet of text as something.reg on your PC, and double click that file. It will add an URI scheme handler for the "emacs" scheme for you. You have to change the path to the program afterwards:

Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\emacs]"URL Protocol"=""
[HKEY_CLASSES_ROOT\emacs\shell]
[HKEY_CLASSES_ROOT\emacs\shell\open]
[HKEY_CLASSES_ROOT\emacs\shell\open\command]@="f:\\Dropbox\\home\\dat\\doc\\src\\bat\\emacsschemehandler.cmd \"%1\""


Step 2 - A script to handle the new URI scheme


To handle the new URI scheme I created a small cmd file that processes the arguments a bit and then starts emacsclient. It looks like this:

REM f:\Dropbox\home\dat\doc\src\bat\emacsschemehandler.cmd

@echo off

REM Pick up all arguments to the script (in case there are spaces)
set emacscommand=%*

REM Stript away the part we don't need...
set emacscommand=%emacscommand:emacs:=%

REM Start emacsclient
f:\Dropbox\home\pgm\emacs-24.3\bin\emacsclient -n -e %emacscommand%

Save the script above as a .cmd file on your computer and update the registry to reflect the path to the .cmd file on your system. Also update the path to where your emacsclient is.

The script is, as can be seen, very simple and basically it just trims off part of the argument from the web browser that we do not need and use the rest as an argument to emacsclient. If you decide to use
another name than "emacs" for your own experiments, make sure to update "emacs:" above to whatever name you picked (plus a colon).


Step 3 - Testing it from a web page


Now you only need a web page with some links to try it out. I have provided a couple of links below that you can try right now, if you decided to use the "emacs" URI scheme, that is. The code for the links looks like this (if you do not trust me, view the source code for this blog post):
<a href='emacs:(message """Hello, Emacs!""")'>Hello, Emacs!</a> <a href="emacs:(calendar)">Open Calendar</a><a href="emacs:(info-emacs-manual)">Open the Emacs manual</a>
Here are the links:

Hello, Emacs!
Open Calendar
Open the Emacs manual

The triple double quotes in the first example are needed in order to send strings from the cmd file to emacsclient. That is why I used single quotes around the href value, which I normally don't like.

Now, what do you wait for, try it! Go go go! :)


So, what can this be used for?


Well, not sure. For me it was mostly a nice experiment, but I can see some uses for people who work a lot in Emacs but also a lot in a web browser and where they need some kind of interaction between
those. Perhaps something nice can be done together with Org mode and documentation of code, where you view the documentation in a browser but let the user try out code in Emacs, or just jump to a particular section in the Org mode document there. I guess the possibilities are endless, as with most things Emacs... :)

Hope you enjoyed it!

C'ya!

2014-10-28

Cake. Can have. Eat too.

A while ago, a friend of mine shared this informative article about why Atom (a new text editor by the Github team, it seems) cannot replace Vim. The author talks about the very useful composability property of Vi(m) and ends his article with this (do read the complete article though, especially if you are quite new to Vi(m)):
A new, shiny, modern editor could one-up Vim by fixing some (or hopefully all) of these issues. But before an editor can replace Vim, it needs to learn everything that 1976 has to teach — not just the lesson of Emacs, but also the lesson of vi.
Well, it might not be very "shiny", and "modern" is, I guess, very subjective, but there is already an editor that both have awesome extensibility and, optionally, strict modal behaviour with a "command" mode.

Which editor it is? Emacs, of course. Just fire up viper-mode, or pick one of the more modern Vi(m) emulation packages like Evil (here is a list of different emulation modes for Emacs) and you can now have your cake and eat it too.

Mmm. Cake.

Keyboard activated favorites menu using "simple menu items"

Some time back I wanted to create a keyboard activated menu with one-key access to some favorite commands that I did not want to give one-key bindings in the global keymap and for which I do not want to type the names on the M-x prompt. I was going to write my own command to read the key for the favorite command. However, it turns out Emacs already had more or less what I wanted in the form of simple menu items.

I chose to use the "apps" key (on keyboards with two Windows keys, it's the key to the right of the right Windows key, with a little menu symbol on it) since I did not use that for anything in Emacs.

Here is how to try this little hack out (FYI the key/command combinations below are just examples and not the actual keys and commands I wanted to use):

(defvar my-favorties-map (make-sparse-keymap "Favorites"))

(define-key global-map (kbd "<apps>") my-favorties-map)

(define-key my-favorties-map (kbd "f") 
  (cons "Find file"
        'find-file))

(define-key my-favorties-map (kbd "s")
  (cons "Save current buffer"
        'save-buffer))

(define-key my-favorties-map (kbd "i")
  (cons "Kill buffer"
        'kill-buffer))

After evaluating the above, when typing the "apps" key, the following "menu" will be displayed in the echo minibuffer:

 Favorites: i = Kill buffer, Save current buffer, Find file

It does what I want, although it is a little bit peculiar in how it decides for what bindings it will show X = Command for, and not. Seems that if the name of the menu item/command begins with the same letter/key that is bound to the command, it will not show it.

So, there it is, an instant little text based menu for executing favorite commands.

Enjoy!

2014-01-31

My Emacs launcher makes me happy

Yeah, just wanted to say that.

Okay, maybe I should elaborate "a little" (...) Some time ago (more than four years I see now...) I got the idea to combine the power of Emacs and the excellent Emacs package Anything (as it was called then, now Helm) plus a keyboard shortcut into my own launcher. Before that I had created a couple of simple ones on my own: PyQe, which I used at home, under Ubuntu (but should in theory work on Windows since it uses basic Python stuff), and another one at work called Quick Execute, which is a small VB hack that turned out to be used by one of my colleagues more than me.

Anyway...

So, Emacs, yes! After some fiddling with the necessary elisp needed and dark (but brittle) voodoo magic configuring a bash script that send keystrokes using some tool I cannot remember the name of now, Anything Launcher was born. It turned out to be a big hit, to me at least (I don't know about anyone in the universe using it, although there were a few comment in the EmacsWiki page early on.)

More than four years later I still use it, several times per hour. What do I do with it? Anything! (of course...) I open important web bookmarks with it, I start programs, I open commonly used folders, I start searches in our intranet at work, I find bugs, cases and Jira issues with it and today I added a small hack to create alarms using the Windows scheduler in the background. And everything I do with it is under total control by me. Not only can I "start" predefined list of "things" (bookmarks etc as mentioned earlier), I can interact with it to give arguments to the "commands" in it.

Just as a more detailed example, if I want to open a bug in our in-house bug tracker, I launch the "Bug Search with prompt" command. It asks me for the bug id and opens the web based bug tracker with the correct bug selected. But, and here comes something that is probably not so easy to do in other configurable launchers (not as easily or quickly I would guess, I am very productive in elisp), it also looks at the clipboard and if it finds something like looks like a bug id, it suggests that as the default input. So, when I get some bug id in some e-mail, I copy that text, open my Emacs launcher (which is what I actually call it on my PC) using a keyboard shortcut, type "bu" to match the bug search command, and then press enter. I then press enter again to accept the bug id it found on the clip board (I could probably make it open the bug directly without me pressing enter, but I like to verify that it is in fact a bug id it found on the clipboard).

That type of command (written in elisp, of course, with all the powers that gives me) turns out to be a quite common pattern, so I have similar commands for cases (connected to bugs), Jira issues and other things where I can "guess" what stuff is placed on the clipboard. And, again, since I have full control and access to an implementation of the world most powerful programming language (Lisp, in case you missed that), I of course implement a command to create these commands. Just as an example on how it could look, here is that exact "bug search" command, from the control file to the launcher:

("Bug Search with prompt" . ("http://urltobugtracker?BUG_ID=%s" "Bug ID" "\\w\\([0-9]+\\)\\w"))

That's it! If I want a similar command for some other web site I just give it another URL (with %s as the placeholder for the input I enter), a prompt for me to understand what to do and the last string up there as regexp for matching stuff on clipboard. Bang! I have a new command that lets me open stuff fast.

The control file, by the way, is actually a normal Lisp list, which the launcher then just "reads". The launcher accepts certain type of "commands", from simple strings that are just started like commands in Windows, to lambda expressions which can do everything that Emacs can do, and Emacs can do A LOT together with external tools. The command above, which begins with a command name and contains as the CDR a list with something that looks like an URL, and some more strings, is also a command that the launcher is programmed to support, since it is such a common command type for me.

Since people like screenshots, here is just an example on how it could look while trying to launch something matching the string "ra":

(please don't make fun of the colours, they can be changed easily but I happen to like them)
So, if you also want to reach launcher nirvana, and just happen to have Emacs lying around, have a look at my Anything Launcher page at EmacsWiki. The information there is a bit old and there are no instructions for Windows, but if there is enough interest (comments here or on the wiki, or by sending me an e-mail or twitter thing or whatever) I might take the time to write down my exact current setup.

Oh, and yes. Some people might ask why I am not simply living inside Emacs all day long and starting things from there. Well, that is not far from the truth either, but sometimes I have to leave the safe haven of Emacs and use other scary programs which people (yet) have not integrated in Emacs and which I don't have the time and effort to integrate myself. So, I need it to be something I can start quickly when I am not inside Emacs (where I, of course, also use Anything to find files and buffers).

Happy launching!


2012-06-27

Using Emacs and ediff as an external diff tool

At work we have a program where one can configure an external diff tool to diff source code changes. Since I am used to work with ediff in Emacs I wanted to use it from that program as well. I ended up making a wrapper cmd file for it and thought I should share it in case someone else wants to solve the same problem.

Here is the script:


@echo off
REM c:\batfiles\ediff.cmd
set file1=%1
set file2=%2
REM Must convert the backslashes to slashes, otherwise they will be
REM interpreted as escape characters in the elisp strings. One can
REM also replace each backlslash with two backslashes to solve the
REM problem, but I like slashes better. Looks less messy.
set file1=%file1:\=/%
set file2=%file2:\=/%
%PATHTOEMACS%\bin\emacsclientw.exe -n -e "(ediff-files ""%file1%"" ""%file2%"")"

Replace %PATHTOEMACS% above with the real path to where you have installed Emacs. After that it's just a matter of selecting this cmd script as the diff tool.

Enjoy!

2009-01-10

Creating multiple shells in Emacs

Sometimes you want to have more than one shell going in Emacs. If you have tried that you know it does not work like you would have expected - you end up in the current shell buffer instead of getting a new one. So I created this small hack:


(defun new-shell (name)
"Start a shell with name NAME, or a generated name if empty.
Returns the name of the new shell."
(interactive "sName: ")
(let ((shell-name
(if (not (string= "" name))
(concat "*shell*<" name ">")
(generate-new-buffer-name "*shell*"))))
(shell shell-name)
shell-name))


It prompts for a name for a new shell buffer. If none is given it will generate one for you. Naming shell buffers can be useful when you are doing a certain kind of work in a certain buffer and want to switch to that buffer easily using parts of the name.

Enjoy!

2008-11-18

I too want to write about Dired...

Inspired by this blog post by Greg Newman about Dired, Emacs' Directory Editor, I wanted to add a few tips myself - I love Dired! Most, if not all, of what I will write about is of course already there in the excellent manual, but it seems that some are as lazy as me and does not always read manuals, so... :)

First a couple of comments to the post Greg did:

Starting Dired

Starting Dired can be done from `C-x C-f' (find-file) as well. Just type a directory name instead of a file name. However, starting it using `C-x d' has certain advantages: you can, for example, enter a file name pattern and the listing will then be limited to that, even if you type `g' to refresh the listing. This can be pretty handy. Also, if you like you can get a recursive listing, a really powerful tool. To do that, use a prefix argument, `C-u', before you execute `C-x d'. You will be prompted for switches to ls. Add a `R' to the existing prompt and type `RET'. Voila! All the power of Dired to a whole directory tree.

Navigation

You can navigate as usual with `C-n' and `C-p' but also with the more convenient `n' and `p'.

Copying and renaming

When copying or renaming you can type arrow down or `M-n' to get the current file's name at the prompt. This is really handy when renaming files. It also works from normal buffers if you use `M-x rename-file' or similar.

You can change the case of file names using the commands `% u' (`dired-upcase') and `% l' (`dired-downcase'). I use it all the time when I have copied photos from my digital camera (I hate those uppercase names, especially the file extensions).

Marking

The basics

At first glance, the concept of marking files in Dired does not seem very special. You mark files with `m' and unmark then with `u' and marked files can be operated on in various ways. I would like to present some powerful tools. First you should learn about the kill command, by default bound to `k', which does not really kill/delete any file, it just removes the file from the listing. You can get it back with the normal `undo' command (available on `C-x u' and other key bindings). Then there is `t' for toggling the marks. Marked files become unmarked and unmarked becomes marked.

Marking by file name or content, and more cool tricks

You can also mark files by matching a regexp against the file name, with `% m', and against the content of the file with `% g'. Together with kill and toggle, these are really powerful tools. Let's say I want to search through all java files in a certain directory for the pattern `'PATTERN and get a listing of only those, after which I want to do some operations (copy, rename, whatever). First I open the directory of interest and do `% m \.java$ RET'. This will mark all files with the .java extension. Next I will kill the rest by first toggling the marks with `t', and then killing them with `k'. Next, use `% g PATTERN RET' to mark only those files that contain PATTERN. When the search is done I do the toggle-kill combo again, and Voila!, I see only the files I want and can do whatever I want to do with them. If you would mark or unmark files or kill files from the listing by mistake, just use undo. Simple as that.

These features alone make Emacs worth learning, at least if you do a lot of file juggling like I do.

The end?

I think this has to do for now. One last thing though: `wdired'. It lets you edit file names as if they were normal text in a buffer, with all the possibilities that gives you with search/replace, rectangle commands etc. It's under the Immediate menu in Dired, under the name `Edit File Names'. Edit the file names and save with `C-x C-s'. Crazily handy for cleaning your mp3-collection :)

I recommend everyone to check out the menus that becomes visible when using Dired. There are a lot of hiddens gems up there. And, of course, read the manual section for Dired for more crazy marking and stuff. Try out `M-x find-dired' some time as well.

Okay okay okay, I said I would stop, and I will. Now.

Thanks for listening!