Skip navigation

Writing heredocs in the shell from emacs presented to me a little nuisance: since the RETurn key is bound to ‘comint-send-input -a function that sends the text to the shell process- I coudn’t re-edit the previous line after having pressed it to insert a simple line break. (I should add that this is actually the usual unix bash behaviour, I only happen to use bash from emacs and so wanted to overcome the problem there)

Yesterday it dawned on me to just use “C-q C-j” under that situation, (that’s how you stick in a line feed in emacs regardless of the mode you are in).

Given that the perspective of typing “C-q C-j” several times looked rather awkward I thought of binding RET with the control key for that:

(global-set-key (quote [(control return)]) (quote newline))

But then, the idea of going the other way around showed more appealing: why not to make newlines with a simple RET, and use the Control key to send the input? Besides, it makes sense to prevent hitting return by accident, I hate when my pinky lands there when searching the pipe “|” key.

While at it I decided to also rebind the TAB functionality so I could further improve the readability of my scripts by indenting them at the same time.

Implementing those changes is simple when you’ve got the luxury of a highly-configurable tool:

(defun my-shell-hook ()
  (local-set-key (quote [(return)]) (quote newline))
  (local-set-key (quote [(control return)]) (quote comint-send-input))
  (local-set-key (kbd "M-i")  'my-unindent)
  (local-set-key (kbd "C-i")  'indent-or-complete))

(add-hook 'shell-mode-hook 'my-shell-hook)

UPDATE: After a day trying this set-up I think that I’d rather stick to the normal binding of the RET key. I’m leaning toward using C-j and C-m instead, as I caught myself reaching to either of them to insert carriage returns. Here are the modified bindings in replacement:

(defun my-shell-hook ()
  (local-set-key (kbd "M-i")  'my-unindent)
  (local-set-key (kbd "C-i")  'indent-or-complete)
; (local-set-key (quote [(return)]) (quote newline))
; (local-set-key (quote [(control return)]) (quote comint-send-input))
;; I actually liked these two better for adding  newlines, leaving the return with it's default behavior
  (local-set-key (quote [(control j)]) (quote newline))
  (local-set-key (quote [(control m)]) (quote newline))
  (local-set-key (quote [(return)]) (quote comint-send-input)))

(add-hook 'shell-mode-hook 'my-shell-hook)

I picked a neat trick at to cancel a command from the shell with “C-q C-c RET” if I need to interrupt a process in a remote shell opened via tramp (only with my windows laptop which I run with cygwin and emacs

Until now, without it, I found it very frustrating for example trying to cancel a heredoc inside a shell: due to some obscure reason, typing “C-c C-c(comint-interrupt-job) rather than get me back at the shell prompt, would kill the connection with the message “Process shell interrupt”.

Again though this alternative is only necessary to me when connected to remote hosts using the windows version of emacs, it’s a sweet discovery nonetheless.

I had an encoding issue that was bugging me inside the remember-data-file. I don’t know exactly how some latin-1 characters copy-pasted there ended up being saved as raw-text and were shown like non-ASCII characters (so a multibyte characters like “é” will appear with it’s escaped octal code “303\251” )

I tried at first setting the file’s encoding system with the tag “-*-coding: utf-8 -*-“, though it seemed not sufficient. The raw characters remained there and I soon grew tired of having to type in: “utf-8” at the prompt to select the encoding every time I needed to save the file.

Today searching the manual found here one easy cure on the command “recode-region” which allows to convert the text that was decoded with the wrong coding system.

Really all it took after marking the whole buffer (C-x h) was doing: “M-x recode-region RET” “Text was was really in: utf-8” “But was interpreted as: raw-text”

That was it!, the drag is over, I’m back to storing notes quickly doing just C-c r and C-c C-x with the worthy remember mode.

(This is mainly a remainder post for myself)
For certain reasons I sometimes have to edit text pasted from an emacs buffer that I was editing with the longlines-mode enabled. Hence as this mode does, the paragraphs are hard wrapped beyond a certain amount of characters (when they extend over ‘fill-column’ lenght).

Although “the soft newlines used for line wrapping will not show up when the text is yanked or saved to disk”, they will remain if, say, I had carelessly pasted it directly into a gmail form to save for later reuse there.

My way to remove those artificially-inserted line breaks, is running this oneliner on the text region.

sed -ne '1h;1!H;${;g;s#\n\([^\n]\)# \1#g;p}' | sed -e 's#^[ \t]*\(.*\)$#\1#g'

(The first sed command tells to put a space and remove the line break. using the multiline search and replace method
The second just gets rid of the leading white space at the beginning of line)

Now that I’m getting fond of using a heredoc to insert mysql scripts into the bash shell, have put this into my emacs initialization file. The same shortcut (Control+Shift+f11) will conveniently write different parameters depending in which shell I’m sitting in.

UPDATE: seems that I spoke too soon. Asking about the present working directory, formerly “(let ((a (shell-command-to-string “pwd | tr -d ‘\\n'”)))”, didn’t actually work when having opened shells of different servers via Tramp.
The correction below (less elegant) depends on the shell buffer being created/renamed with an identifiable name -which could be the hostname or whatever consistent nomenclature we choose-.
Anyway, until figuring a better way, this does the job of inserting the right parameters into each shell:

(defun my-heredoc-sql-invocation-from-shell ()
"Insert the appropiate parameters to run a heredoc mysql query depending on which shell I'm in"
  (let ((a (buffer-name (window-buffer (minibuffer-selected-window))))
        (b nil))
    (cond ((string-match "serverA" a) 
           (setq b "mysql -uroot mainDbToHitAt_A--password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverB" a) 
           (setq b "mysql -ualpha mainDbToHitAt_B --password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverC" a) 
           (setq b "mysql -uroot mainDbToHitAt_C  -t <<\\!")))
    (insert b)))

;; key shortcut to bind it to
(global-set-key (kbd "C-S-<f11>")  'my-heredoc-sql-invocation-from-shell)

Despite being dealing with databases for some years it was just recently that I started to run mysql queries straight from the shell by doing something like:

mysql -u(user) -p(password)  -t -e ‘whatever sql query here in one line’

Although a handy way to use every now and then, I still felt this sort of limited since the query to be passed in the “-e” argument must go inside a single line. In search of  a better alternative I was pleased to figure instead that it’s possible to combine heredoc sintaxis with the sql execution in the command line. Heredoc is a mechanism to break text into multiple lines, just as a file would be treated, after the “<<” sign, the parser says: “here follows a document” which gets wrapped inside the pair of whatever text delimeters we choose. The obvious convenience is that without having to create a file we could easily run multiline queries -which read more naturally with line breaks and indentation- in the same way we would write them inside a file.

To quickly see what I’m talking about type

mysql -u(yourDatabaseUserName) -p(your Password)   -t<<eof
show databases

Now hit “Control D” and then, “Enter” to see the output directly thrown at your shell

To speed things up, since  I use the shell inside emacs, I bound the following to C-S f11 adding  what is below into my .emacs file:

(set-register ?q “mysql -u kabul -p ******** -t <<eofsql”)
(defalias ‘Q
(read-kbd-macro “M-x insert-register RET Q C-e “))
(global-set-key [C-S-f11] ‘Q)

In a bash shell, I knew about the way to produce the output of a query into a tab delimited file by simply running:

mysql -uUSER -pPASSW < fileWithSQLquery.sql >

Now in this case what I needed was a CSV file, for which I piped it to sed reeplacing tabs by commas doing:

mysql -uUSER -pPASSW < fileWithSQLquery.sql | sed -e ‘s#\t#, #g’ > fileToSave.csv

here’s an example of how to run php in the command line, something I almost never do and would like to remember by writing it down.
Simply echo the php statement (within its corresponding tags) and pipe it to the php service. Eg:

echo ‘<?php $str = ‘2144338’; echo substr($str,0,2); ?>’ | php

or even more usefully:

echo ‘<?php  phpinfo(); ?>’ | php

I sometimes forget about the exact name of a file I was working a while ago. Luckily the way to state a range of time with find is quite intuitive; say that we want to see the files modified in a lapse of 14 days starting from a week ago:

find . -ctime +7  -ctime -21 # (older than 7 days but newer than three weeks ago)

There are simply 3 options of numeric arguments for time

  1. +n –> More than ‘n’ days ago.
  2. -n –> Less than ‘n’ days ago.
  3. n —> Exactly ‘n’ days ago.

I struggled the other day doing some sys admin work for recovering data from a single table of our database. Editing big files (of about several gigabites) is no-picnic even for vi(m) or emacs, so it wasn’t trivial to find a quick way to isolate the parts needed. For what is worth here’s the method I’ve followed with success resourcing to simple cat and sed commands in my command line:

  1. Get the creation statement for the table to be recovered

    cat your_entire_backup_file.sql | sed -ne '/Table structure for table `your_table`/,/-- Dump/p' > table_creation.sql
  2. Get the data

    cat your_entire_backup_file.sql | sed -ne '/INSERT INTO `your_table`/,/Table structure/p' > data_dump.sql
  3. Join the two into a single file

    cat table_creation.sql data_dump.sql > data_for_single_table_to_copy
  4. Optionally, in case you need to extract some rows only from that previous instance of the table, as it was my case with records deleted by mistake, you might want to create a temporary table from where to later perfom the selection of the desired rows. In order to do that, the table name should be altered from the creation and insertion statements:

    sed -i 's#your_table#your_temp_table#g' data_for_single_table_to_copy.sql
  5. Now we are ready to create that temporary table with its data inside our database:

    mysql -u 'your_username -p your_database_name < 'your_path_to_the_file/data_for_single_table_to_copy.sql
  6. Voila!, the table is there containing the information you needed. Now is up to you to extract and reinsert whatever you wanted inside the original table

Note: See that different parameters could be used to isolate and put together table creation and data parts in only one pass. Also the awk command might be used instead since, like sed, it permits collecting portions by matching from the beginning to the ending block of text. Just make sure you know the order of the table after the one you are picking.

awk '/Table structure for table `your_table`/,/Table structure for table `your_next_table`/{print}' your_entire_backup_file.sql > data_for_single_table_to_copy.sql

In case the table to extract happens to be the last one (which again, you could just know with a mysq “show tables” command, modify the last part of the regexp to match it accordingly.