How do I delete the newline from a process output? - elisp

I call git get the toplevel dir (according to
Is there a way to get the git root directory in one command?
).
(let ((tmpbuffer (get-buffer-create (make-temp-name "git"))))
(call-process "git" nil tmpbuffer nil "rev-parse" "--show-toplevel")
(with-current-buffer tmpbuffer
(with-output-to-string
(princ (buffer-string))
(kill-buffer))))
But there's a trailing newline in the string returned. I'm not sure how to get rid of it.

I think you can do
(replace-regexp-in-string "\n$" ""
(shell-command-to-string "git rev-parse --show-toplevel"))

If you only want to remove a newline at the very end of the output, use
(replace-regexp-in-string "\n\\'" ""
(shell-command-to-string "git rev-parse --show-toplevel"))
The accepted answer also replaces pairs of newlines ("\n\n") in the output by single newlines ("\n"), because $ matches at the end of the string or after a newline, while \\' only matches at the end of the string.

Assuming it is stored in a variable output-string, the final newline at the end can be removed this way:
(substring output-string 0 -1)
With the shell-command way, it would look like this:
(substring
(shell-command-to-string "git rev-parse --show-toplevel")
0 -1)

If You are OK with awesome external package.
use s-trim
ELISP> (shell-command-to-string "light -G")
"60.00\n"
ELISP> (s-trim (shell-command-to-string "light -G"))
"60.00"

Related

Resize image by percentage on both x and y on command line with Gimp

AFAIK, it should be possible. I know that convert of ImageMagick makes this task trivial, but I cannot use ImageMagick, therefore I am leaning towards Gimp (on Windows).
I have tried with this Guile script:
(define (resize-image filename new-filename scale)
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image)))
(width (gimp-image-width image))
(height (gimp-image-height image)))
(gimp-image-scale-full image (* width scale) (* height scale) INTERPOLATION-CUBIC)
(gimp-file-save RUN-NONINTERACTIVE image drawable new-filename new-filename)
(gimp-image-delete image)))
that I run with:
gimp-2.8 -i -b "(resize-image \"image.jpg\" \"image-small.jpg\" 0.5)" -b "(gimp-quit 0)"
but I get this error:
(gimp-2.8:22244): LibGimpBase-WARNING **: gimp-2.8: gimp_wire_read(): error
(gimp-2.8:22244): LibGimpBase-WARNING **: gimp-2.8: gimp_wire_read(): error
batch command experienced an execution error:
Error: ( : 1) *: argument 1 must be: number
My solution has been inspired by this post:
http://warunapw.blogspot.it/2010/01/batch-resize-images-in-gimp.html
The shortest code to scale down an image:
image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png')
image.scale(int(image.width*.5),int(image.height*.5))
pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')
So, you can still put everything in a one liner. In Linux, that gives (brace yourself):
gimp -idf --batch-interpreter python-fu-eval -b 'image=pdb.gimp_file_load("/tmp/bigger.png","/tmp/bigger.png");image.scale(int(image.width*.5),int(image.height*.5));pdb.gimp_file_save(image, image.active_layer, "/tmp/smaller.png","/tmp/smaller.png")' -b 'pdb.gimp_quit(1)'
IIRC, due to how to the Windows shell uses quotes, you have to use double quotes to delimit shell parameters so things are easier if you use single quotes around Python strings (untested):
gimp -idf --batch-interpreter python-fu-eval -b "image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png');image.scale(int(image.width*.5),int(image.height*.5));pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')" -b "pdb.gimp_quit(1)"
However, there is significant overhead when starting Gimp (especially on WIndows), so if you need to process several files, you may be better off writing code that loops over files in a directory. This gets a bit bigger and may want to keep the code in a module. From my archives from a former life as a windows user:
Assume you have a batch.py file like this (you'll obviously have to improve the process() function, in particular pass parameters to it:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import os,glob,sys,time
from gimpfu import *
def process(infile):
print "Processing file %s " % infile
image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png');
image.scale(int(image.width*.5),int(image.height*.5));
pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')
pdb.gimp_image_delete(image)
def run(directory):
start=time.time()
print "Running on directory \"%s\"" % directory
for infile in glob.glob(os.path.join(directory, '*.jpg')):
process(infile)
end=time.time()
print "Finished, total processing time: %.2f seconds" % (end-start)
if __name__ == "__main__":
print "Running as __main__ with args: %s" % sys.argv
You would call it (in Windows) as:
gimp -idf --batch-interpreter python-fu-eval -b "import sys;sys.path=['.']+sys.path;import batch;batch.run('./images')" -b "pdb.gimp_quit(1)"

Extract text from gimp xcf files

I can't get out from lisp, to pass to bash, in the same script...
#!/bin/bash
{
gimp -n -i -b - <<EOF
(let* ( (file's (cadr (file-glob "*.xcf" 1))) (filename "") (image 0) (number 0) (condition 0) (testo "") )
(while (pair? file's)
...
(gimp-quit 0)
)
EOF
}
echo $testo;
The value of testo in your gimp code will not be reflected in your shell's environment. To do that, you would need to print the value and capture the output.
The general way of doing that in shell is var=$(command) (this sets the value of var to the standard output from command).

Unable to print array in bash shell

I have been using tcl shell on windows but while assisting someone on bash found a weird issue:
export SERVER_HOSTNAME=server1
export USERNAME=root
export PASSWORD=pswd
export LOG_FILE="a.log"
export LOG_PATH="$env(LOG_PATH)"
export log_search_pattern="Filterable_data"
/usr/bin/expect<<EOF
set lineNum {}
set SERVER_HOSTNAME "$env(SERVER_HOSTNAME)"
set USERNAME "$env(USERNAME)"
set PASSWORD "$env(PASSWORD)"
set LOG_FILE "$env(LOG_FILE)"
set log_search_pattern "$env(log_search_pattern)"
set timeout -1
spawn ssh "$USERNAME#$SERVER_HOSTNAME"
expect "assword:"
puts "$expect_out(buffer)"
parray expect_out
send "$PASSWORD\r"
expect "#"
puts "$expect_out(buffer)"
send "grep -n $log_search_pattern $LOG_PATH/$LOG_FILE|tail -1\r"
expect eof
EOF
Now the issue is that the following command:
puts "$expect_out(buffer)"
prints -> (buffer)
But prints the entire buffer contents
parray expect_out
I also tried adding following lines:
set a(1) val1
set a(2) val2
puts $a(1)
puts $a(2)
parray a
It printed:
(1)
(2)
a(1) = val1
a(2) = val2
I tried various combinations to get the puts $a(1) to print val1 but it always printed (1).
What's the correct method to do so?
Variables expand in HEREDOCs. If you want to avoid that you need to quote some or all of the opening HEREDOC marker (i.e. <<'EOF') (but not the closing one).
From Here Documents in the bash reference manual:
The format of here-documents is:
<<[-]word
here-document
delimiter
If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded.
So when you have:
puts "$expect_out(buffer)"
in the HEREDOC and expect expect to see that literal string it actually sees:
puts (buffer)
because the shell has removed the quotes and expanded the $expect_out variable for you.

How do I display the git branch in the emacs modeline?

By default the modeline likeļ¼š
Emacs displays Git-master when I am working in a directory that is under the Git version control system.Now I customize modeline in the file init-modeline.el like this:
(setq-default mode-line-format
(list
;; the buffer name; the file name as a tool tip
'(:eval (propertize "%b " 'face font-lock-keyword-face
'help-echo (buffer-file-name)))
;; line and column
"("
"%02l" "," "%01c"
") "
......
))
Then add (require 'init-modeline) to init.el.
Now emacs does not display git branch in the emacs modeline, so I add '(vc-mode vc-mode) to init-modeline.el like this:
(setq-default mode-line-format
(list
;; the buffer name; the file name as a tool tip
'(:eval (propertize "%b " 'face font-lock-keyword-face
'help-echo (buffer-file-name)))
;; line and column
"("
"%02l" "," "%01c"
") "
'(vc-mode vc-mode)
......
))
Now modeline shows like this:
It only shows -master.How can I show Git-master?
The value of variable vc-mode in init-mode buffer like:
vc-mode's value is #(" :master" 0 1
(face sml/vc-edited)
1 8
(help-echo "Locally modified file under the Git version control system\nCurrent revision: master\nmouse-1: Version Control menu" face sml/vc-edited local-map
(keymap
(mode-line keymap
(down-mouse-1 menu-item "Version Control" vc-menu-map :filter vc-menu-map-filter)))
mouse-face mode-line-highlight))
Local in buffer init.el; global value is nil
Automatically becomes permanently buffer-local when set.
This variable may be risky if used as a file-local variable.

Calling a custom emacs function with arguments

I've got this function in my .bash_rc:
function ForwardSearchXdvi {
latex -src *.tex;
for i in *.dvi; do xdvi -sourceposition "$1 ${i/.dvi/.tex}" $i; done ;
}
it works... I call it by command line with the $1 argument (the target line number in my file.tex) and it's fine.
I'd like to run it directly from emacs so I made this command:
(defun ForwardXdviSearch ()
(interactive)
(shell-command (format "bash -ic %s" (shell-quote-argument "latex -src J[HCI]*.tex; for i in J[HCI]*.dvi; do xdvi -sourceposition \"$1 ${i/.dvi/.tex}\" $i; done ;")))
)
How can I pass the argument $1 to the function when I call it with "M-x Function" ?
You would need to use special form interactive for reading arguments. Something like this untested code:
(defun forward-xdvi-search (line-number)
(interactive "nForward to line: ")
(shell-command
(format "bash -ic %s"
(shell-quote-argument
(format "latex -src J[HCI]\*.tex; for i in J[HCI]\*.dvi; do xdvi -sourceposition \"%d ${i/.dvi/.tex}\" $i; done ;"
line-number)))))
Edited with the improvement suggested by #phils

Resources