Open emacs application in a specific mode for given path - macos

I was using emacs on command line and I was using following command to open current git directory in magit mode:
emacs -nw -f magit-status --eval "(call-interactively #'delete-other-windows)"
I switched to using emacs app instead of opening it in command line. I am using following command alias:
alias emacs='open -a /Applications/Emacs.app $1'
Because of this magit command doesn't work anymore. Is there any way to achieve the same functionality with Emacs app?
Also, tried this function as suggested in comments:
function magit() {
open -a /Applications/Emacs.app --args -f magit-status $1
}
Regards,
Pawan.

When starting a new Emacs session, the function
function magit() {
open -a Emacs --args --file "$1" -f magit-status
}
will do what you want. That is, load a file into a buffer (via find-file) and run the function magit-status on that buffer. Note, that order counts on the Emacs command line. While open -a Emacs myfile --args -f magit-status and open -a Emacs --args -f magit-status myfile are correct from the perspective of open, they aren't correct from Emacs's perspective. (magit-status is executed on nothing, and then myfile is opened. Not what you want.)
If you want to do this with a currently running Emacs session, you can't. The clue is in open's manpage.
--args
All remaining arguments are passed to the opened application in the argv parameter to main(). These argu-
ments are not opened or interpreted by the open tool.
main() has already executed, so you can't pass anymore parameters to it, so --args is effectively ignored. So, you'll have to get creative with the Emacs server and emacsclient.
If you have an open Emacs session with an associated server (via server-start for instance), you can do the following to "load and execute-on" a file
# my emacs will load *.log files in `fundamental-mode`
# this will load them in `text-mode`
$ emacsclient -e '(find-file "/tmp/foo.log")' -e '(text-mode)'
# or
$ emacsclient -e '(progn (find-file "/tmp/foo.log") (text-mode))'

Related

How do I use emacs on macos terminal?

I downloaded Emacs for MacOS and created a file called emacsclient using ln -s /Applications/Emacs.app/Contents/MacOS/bin/emacsclient /usr/local/bin
Then created a script called ec in my PATH with the contents
#!/bin/sh
which osascript > /dev/null 2>&1 && osascript -e 'tell application "Emacs" to activate'
emacsclient -c "$#"
The above steps were from Emacs for MacOS
I then set an alias using alias emacs="emacsclient -t --socket-name=/tmp/emacs1000/server" so that i could call emacsclient using just emacs.
when I call emacs I get the message
emacsclient: can't find socket; have you started the server?
emacsclient: To start the server in Emacs, type "M-x server-start".
emacsclient: error accessing socket "/tmp/emacs1000/server"
I am a beginner and don't really know much.
Thanks
The command emacsclient -t --socket-name=/tmp/emacs1000/serverwill work only if you've started a emacs server first.
To launch a emacs server, execute the following command :
emacs --daemon
After that, the command emacsclient -t will open a new Emacs frame INSIDE the terminal. If you want to have an "outside the terminal" Emacs frame launch emacsclient -n.
What I recommend is to have the command emacs --deamon launch at startup, and I binded "Ctrl-Alt e" to emacsclient -n to launch new Emacs frame with a quick shortcut.
Finally, you can find a lot of information on the GNU documentation of Emacs, here is the page for the emacsclient command : GNU's documentation on emacsclient

Sending Bash Aliases to detached screen sessions

I'm on a Linux machine using screen, and I'm attempting to write a (fairly portable) function which runs a bash function in a new, detached screen session which automatically closes upon completion. I've had some success, but I noticed the following behavior:
If I include the definition of mail_submit() in my ~/.bashrc file, I can run
mail_submit foo
in the terminal, and also I can access the alias in a new screen session:
screen -S test
mail_submit foo
However, the following command does not work:
screen -d -m -S test sh -c 'mail_submit foo'
presumably because sh -c starts a fresh shell that has no knowledge of my ~/.bashrc profile. So, I can use the following fix:
screen -d -m -S test sh -c 'source ~/.bashrc; mail_submit foo'
which does work.
But if I want to wrap this functionality up into a bash alias (which is my ultimate goal here), this will cause a weird self-referential situation.
Question: What is an easy way to either have sh -c know the location of my ~/.bashrc profile, or use a variant of sourcing the file and creating an alias?
EDIT: I could save the shell script in my home directory, and create an alias which runs
screen -d -m -S test bash -c '~/mail_submit.sh $1'
but I'd still be curious to hear other possible fixes.
A default ~/.bashrc contains this ([[ "$-" != *i* ]] && return) little piece of code on top of it (or somewhere else in the upper part). This line will prevent the ~/.bashrc from beeing sourced if the bash shell doesn't run in interactive mode.
You could:
Remove this line
Create a new file which will only contain the alias you need and source that
Create a little bash script instead of an alias and run that
Do you mean screen -d -m -S test bash -c 'mail_submit foo'?
It looks like you're trying to run the command with the shell (sh), and not the bourne again shell (bash), which is the shell interpreter which actually reads the ~/.bashrc profile.
Edit: The .bashrc file is not being sourced by default because screen does not create the bash process as a login shell, which is when the .bashrc file is read. Creating a .screenrc file with the line defshell -bash will create the bash process as a login shell instead, which will then call the .bashrc file.

Launch Visual Studio CODE editor from terminal as root on OS X

According to the documentation off Visual Studio CODE, you can open the editor from terminal by adding the following lines to your .bash_profile on OS X.
code () { VSCODE_CWD="$PWD" open -n -b "com.microsoft.VSCode" --args $* ;}
That just works.
Now the question is, what needs to be done to allow the command to work if you try to launch it with administrator privileges.?
ie:
sudo code .
One way would be to add a sudo version to your .bash_profile
sucode () { VSCODE_CWD="$PWD" sudo open -n -b "com.microsoft.VSCode" --args $* ;}
This is a problem that has been asked (and answered) in these posts.
How can I execute a bash function with sudo? (Server fault)
How can I execute a bash function using sudo? (Stack overflow)

How to launch tmux with pre-opened second window and execute commands?

There's possible duplicate but it's closed and unanswered.
As I'm using chef for automation, would be nice to automate tmux launch with pre-launched python web server and second window opened. (this is specifically for my development environment). And only way of doing this probably specifying parameters from command line.
Commands which I want to execute are in window with title "daemon":
source bin/activate
cd project
DEBUG=1 python app.py
I'm unable to find which command line parameters allows to pre-execute commands when launching tmux, and also to open more windows on launch.
You want to create a session without attaching to it (using the -d option), so that you can send additional tmux commands to open the second window before actually attaching.
tmux new-session -t mysession -d 'source bin/activate; cd project; DEBUG=1 python app.py'
tmux new-window -t mysession
tmux attach-session -t mysession

Open gnome terminal programmatically and execute commands after bashrc was executed

I try to build a little script to start my development environment. For that task I try to open a gnome terminal with several tabs where automatically the rails server and autotest is started.
But
gnome-terminal --tab -e "rails server" --tab --tab
does not work ("error creating the child process").
Also
gnome-terminal --tab -e "bash -c \"rails server\"" --tab --tab`
does not work.
Any suggestions how to solve that problem?
Here is a nice trick we worked out at Superuser
Add a eval "$BASH_POST_RC" to the end of your .bashrc
Set the BASH_POST_RC environment variable for each tab to that command you like to execute, e.g.: gnome-terminal --working-directory="/home/zardoz/projects/my_rails_app" --tab -e 'bash -c "export BASH_POST_RC=\"rails server\"; exec bash"' --tab -e 'bash -c "export BASH_POST_RC=\"autotest\"; exec bash"'
#Gilles: Thanks for that solution!
Stab in the dark: create shell scripts for each command you want to run in a tab, make them executable, and invoke them by absolute path, e.g. put this in /home/zardoz/bin/railsstart
#! /bin/sh
exec rails server
chmod +x it, and then do
gnome-terminal --tab -e /home/zardoz/bin/railsstart --tab --tab ...
If that doesn't work, the next thing I would try is sticking strace -f -o /tmp/trace.log on the beginning of the command, letting it fail, and then digging through trace.log to find out which system call actually failed and why (there'll be a tremendous amount of junk in there - read from the end backward and look for all-capitalized code phrases starting with E, like "ENOEXEC", "ENOENT", "EPERM", sort of thing.)
EDIT: Here's how you pull in all the .bashrc settings in one of these scripts:
#! /bin/bash
. ~/.bashrc
exec rails server
Caution: you may need to adjust your .bashrc so that it doesn't do certain things that only work in a "real" interactive shell session. Don't worry about this unless you get strange errors before rails starts.
I'm assuming the error arises because PATH is not set at the time gnome-terminal tries to run rails.
Why not use the full path to the rails server, or create a script that sets the PATH variable?
Already replied, but just in case, check out this gem that automates the terminal on KDE, OSX and Gnome desktops.
for ubuntu 16.04
press Ctr+Shift+T
this will open a new tab in the same window. additionally a button for adding more tabs will appear next to the right most tab.

Resources