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

Thursday, 16 November 2017

Toggle Read-only behaviour of buffer in Emacs

When a file to which you have read access as regular user is opened in emacs, the buffer is marked read-only. If the user escalates to root and opens the same file in emacs, the buffer still remains read-only. To modify the file, the user needs to toggle the read-only behaviour of the buffer (for which the default key binding is C-x C-q) first.

Sunday, 25 May 2014

Compiling in Emacs

I use Emacs for development in C. I was trying out some algorithms and I had used some functions from math.h. I had included the header of course. However, when I wanted to compile I knew I would have to use the -lm flag to include math.h in the compilation. I use M-x compile for compilation. It usually asks me to enter the name of the executable to be built. In that same line, I added the CFLAGS=-lm part to the end of that line and the compilation worked fine. So instead of

make -k application

my compilation command looked like the following.

make -k application CFLAGS=-lm

Sunday, 16 March 2014

Starting with Lisp

Just for some fun and relaxation, I decided to start doing some Lisp. I had set up SLIME a few months backs while I was starting some book but I had not done much. I decided to use SBCL because I had read that is usually fast. The reason I was using SLIME is that the back arrow key does not work when I use the SBCL REPL and that is very annoying to me because I type both opening and closing parentheses together and type the rest of the code in between. To setup SLIME, a lot of documentation is available online so I wont re-iterate. Just for reference, the SLIME section of the .emacs file is as follows:

(setq inferior-lisp-program "/usr/bin/sbcl")
(add-to-list 'load-path "/usr/share/emacs/site-lisp/slime/")
(require 'slime)
(slime-setup)

Once I was in SLIME REPL, I started writing a few s-expression to get a hang of it.

(+ 1 2)

(print 'hello)

(format t "hello world")


After that, I started writing a simple function that returns the nth number in the Fibonacci sequence. I came up with the following.


(defun foo (n)
    (cond
     ((= n 1) 0)
     ((= n 2) (+ 1 (foo (- n 1))))
     (+ (foo (- n 1)) (foo (- n 2)))))


And I started testing it.


(foo 1)

(foo 2)
(foo 3)


The result for n = 3 was wrong. The reason lay in the last section of cond. I intended it to be default but I had not specified the condition for it. So, I corrected it as follows.

(defun foo (n)
    (cond
     ((= n 1) 0)
     ((= n 2) (+ 1 (foo (- n 1))))
     (t (+ (foo (- n 1)) (foo (- n 2))))))

Now, the method was returning correct values. Clearly, it is a bad implementation. So, I thought the calls to foo should be memoized. I could go ahead and try writing my own memoization but I wanted to see what Common Lisp had to offer. However, before doing that I wanted to know whether memoization will be beneficial. So, I wanted to benchmark the memoized and the plain versions. Our good friend Google helped me out. I was able to start profiling using SBCL's built-in package sb-prof.


(in-package :cl-user)
(require :sb-sprof)
(declaim (optimize speed))
(sb-sprof:with-profiling (:max-samples 1000
                          :report :flat
                          :loop nil)
  (foo 100))


I was a little doubtful that I should not be trying for the 100th Fibonacci number but still I went ahead with it and even after some minutes, it was going on. So, I now I decided to kill the profiling. Ctrl+C Ctrl+C came in handy. I started low this time. From 10, 15, 25, I reached up to 40 at which value it took around 6 seconds.


(sb-sprof:with-profiling (:max-samples 1000
                          :report :flat
                          :loop nil)
  (foo 40))


Now, I was ready to test a memoized version of the function and see how much benefit I can get. I remembered reading some code by Peter Norvig in Python which used a decorator to achieve generic memoization. So, I thought Lisp ought to have something similar. I found a nice memoization API. However, I had to install the package and I did not want to delve into that because I did not find any packages for Arch. So, I decided to settle for a less robust implementation.

(defun Basic-Memo (Function)
  "Takes a normal function object and returns an `equivalent' memoized one"
  (let ((Hash-Table (make-hash-table)))
    #'(lambda (Arg)
    (multiple-value-bind (Value Foundp)
        (gethash Arg Hash-Table)
      (if
        Foundp
        Value
        (setf (gethash Arg Hash-Table) (funcall Function Arg))))) ))

(defun Basic-Memoize (Function-Name)
  "Memoize function associated with Function-Name. Simplified version"
  (setf (symbol-function Function-Name)
    (Basic-Memo (symbol-function Function-Name))))

(Basic-Memoize 'foo)
Now, the 1000th Fibonacci number was also easily calculated. When I tried to the above profiling code for (foo 1000), I was getting error for the run being too short. Trying for 10000th Fibonacci number, I got 0.01 seconds.

Saturday, 21 December 2013

Spellcheck in Emacs

Recently I am using Emacs for writing a few essays. While writing, I started missing spellcheck feature of Microsoft Word. The fact that feature is also provided my many browser based tools, like in GMail has made me used to it. So, I did a quick lookup to find the shortcut for triggering spellcheck in the current Emacs buffer. The answer was to simply use M-x ispell. Trying that I got the following error in the Messages buffer below the main buffer.

No word lists can be found for the language "en_US"

The shortcut mentioned above uses aspell which I knew is installed on my system. So, looking for aspell errors, I figured I needed to install the package aspell-en to get it fixed. On Arch linux, it can be done using the following.

pacman -S aspell-en

Saturday, 6 October 2012

Formatting column entries for IN query

Extracting entries of a column in a spreadsheet and using them in an IN query is not a rare scenario [at least for me] at work. Now, copying and pasting the entries in a comma separated and sometimes quote-enclosed format is tedious and when there are 100 entries, doing that by hand is unacceptable for me. On top of that when each entry has to be modified a bit before passing in the IN query, then the whole process becomes drudgery. Today, when faced with such a situation, I used emacs and sed to save myself a lot of time and boredom.

Let us consider that the spreadsheet has a column that has the following entries:

12345-1
23456-2
34567-1
45678-1
56789-1

Now, lets consider that I have to strip the first suffix, enclose the values in quotes and pass them in the IN query. So, I copy the column and paste in a text file and run the following commands on the file.


sed -i 's/-1//' ./myfile.txt
sed -i 's/-2//' ./myfile.txt

Now the file had the following contents.

12345
23456
34567
45678
56789

Now, I opened the file in emacs and ran a keyboard macro to get the following string.

'12345', '23456', '34567', '45678', '56789',

Now, I could easily use it in my query. Now, the macro I used was simple. I started recording the macro using `C-x ('. The macro consisted of the following keys in sequence [try it yourself to be clear]:

' -> End -> ' -> , -> Delete -> Space

I ended recording the macro using `C-x )'. Now, I had one line edited so I let emacs run the macro 4 times using the following command:

C-u 4 C-x e

I got the inspiration for using macros in the following video.


Sunday, 18 September 2011

Using Emacs for development

When I started working with linux, I had the choice of the following text editors:
  • KEdit
  • Vim
  • Emacs

I decided to try all of them. After initial try, I was certain I would not use vi. It just did not suit my tastes. KEdit turned out to be limited in functionality. So, Emacs became my editor of choice. Initially, I was using it for trivial tasks only. Gradually as I knew more about it, I started using it more.

Compiling and debugging in emacs was fine. However, I was missing code navigation features which really come in handy during code reading phases. Searching through the world wide web, I found this blog explaining the use of etags with emacs for code navigation. I gave it a shot and it surely is fast. While working with python, I found emacs' support for python is not that good; but I am sure it will improve soon.

Friday, 24 June 2011

Mouse vs keyboard


Over the years, we have had a conflict between two groups of users: GUI-friendly and CLI-friendly. Mostly the CLI-friendly people think that the keyboard is faster than mouse while the GUI-friendly people think that the mouse is faster. A research by Apple shows that actually it is the mouse that is faster in most cases although people think the keyboard to be. However, it is not the metrics that matter; but the mentality that is developed.

A programmer typing in full flow is very unlikely to break his flow and hold the mouse. He probably would prefer the whole window to be controllable from the keyboard. That way the interface is letting the programmer do his job without being distracted towards using a mouse. Emacs is a classic example of this.

However, people who work primarily with the mouse like desktop users who are copying files or playing music can use the mouse with ease letting the other hand rest.

Apple and Microsoft provide a nice GUI interface and are doing good business because most of their users are GUI-friendly. However, linux allows choice. There are great GUI windows managers like Enlightenment and there are also tiling window managers like awesome.

Monday, 23 November 2009

Cooked linux console

Recently while I was playing around with code, there was a log line
printf("foo: skipped '%c'\n", c);

When c was a carriage return; the log line obtained was
'oo: skipped '
This was because carriage return takes the current position to the beginning of the line. Now, as the linux console is cooked by default [Most *nix programs get their tty input via the kernel tty driver in `cooked' mode.], it formatted the whole line and printed the line at once producing the effect.

A simple way to detect parts where the "cooked" console interferes is to run the command from within emacs. Emacs does its own input handling and is not cooked. The same log line in emacs is shown as:
foo: skipped '^M'


These petty issues must be kept in mind while considering portability of software.