Always open a txt file using specified app in fish shell - fish

I use fish shell. I always open *.txt files in atom, so I need to type atom filename.txt. I know, that in zsh, there's an option to always open files with some extension in the specific app using alias -s option. Is there a way to achieve the same behavior in fish shell?

Sorry, fish does not support this. Your best bet is to define an ordinary function/alias that calls into atom.

Two solutions come to mind. First, use an abbreviation or function to reduce the number of characters you have to type:
abbr a atom
Now you can just type "a *.txt". The advantage of doing function a; atom $argv; end is that it allows for more complicated steps than just replacing a short command with a longer command. As another example, I have abbr gcm "git checkout master" in my config because that's something I do frequently.
Second, use a key binding. For example, arrange for pressing [meta-a] to insert "atom" at the start of the command and execute it:
function edit_with_atom
set -l line (commandline -b)
commandline -r "atom $line"
commandline -f execute
end
bind \ea edit_with_atom
The key binding allows for more complicated operations than what I've shown above since you can execute arbitrary code.
These solutions don't scale but if there's just a couple of commands you run frequently that you want to invoke with fewer keystrokes they might help.

Related

what does "commandline -f repaint" in fish shell?

While trying to debug a prompt problem in my fish shell, I read that the nextd-or-forward-word function calls the commandline builtin function with the "-f repaint" arguments.
I simply can't understand what it does.
The documentation for the "commandline -f" says it "inject readline functions into the reader", what does that mean ?
I am not even sure of what is "readline" here. Is it the GNU C library ?
Assuming it is, I can't find any mention of "repaint" in the GNU readline documentation.
Can you explain that to me ?
The documentation for the "commandline -f" says it "inject readline functions into the reader"
In simple terms, it's commands for fish's commandline reader module. (The documentation is a bit jargon-heavy here, yes)
So commandline -f repaint tells fish to "repaint" the prompt. That means it'll execute the fish_prompt, fish_mode_prompt and fish_right_prompt functions again, and redraw their output.
In case of nextd-or-forward-word, it does repaint so the prompt's $PWD display gets updated. If it didn't do that, nextd would move you to a different directory, but since you've not executed a normal command in a commandline, the prompt would stay the same. And redrawing after every input isn't tenable because the prompt can take a while.
Is it the GNU C library ?
This would be one thing that the GNU "readline" library would do if fish used it. So fish internally uses the term "readline" as well for things that have to do with reading lines, and it's leaking into the docs.

Setting TERM variable for Emacs shell

Is it possible to set the TERM environment variable for Emacs shell to some other value than "dumb"? In order to make TRAMP work I'm adjusting some parts of .bashrc on remote machines according to $TERM == "dumb" condition but for the shell I'd like these ignored (opposite approach - setting the TERM for TRUMP - would also be applicable).
Let me give your answer in two parts: first, one that technically answers your question but isn't very useful, and second, one that probably answers your needs even though it takes a different tack to get there.
Setting TERM in the shell
When starting shell-mode with M-x shell, Emacs starts the shell you want (usually the same as your login shell, but this can be changed if you really want to) and then sources a file, if it exists, based on the shell's name. The places it looks are
~/.emacs_$SHELLNAME
~/.emacs.d/init_${SHELLNAME}.sh
In this file you can set TERM. For instance, if you use zsh, and create the file
# ~/.emacs_zsh or ~/.emacs.d/init_zsh.sh
export TERM=emacs
then you'll get what you asked for: shells started with M-x shell will have the TERM set to emacs instead of dumb.
While this technically answers your question, though, it's not particularly useful—if you try it, here's what you'll get when you start a shell:
zsh: can't find terminal definition for emacs
$ echo $TERM
emacs
$
The issue here is that shell-mode doesn't implement any terminal emulation. In other words, dumb is exactly the right TERM value to use.
(Note there are modes that emulate terminals—see, for instance, M-x ansi-term—and they set TERM=eterm-color or similar, but they're designed to let you use Emacs as an xterm replacement for visual-mode shell commands, whereas M-x shell is designed to let you run shell commands while still interacting with the input and output in an Emacs-y way.)
When you choose a TERM value that isn't supported by termcap, you'll get the above error and some programs may get confused about what's happening (and some will refuse to run at all). If you select a full-featured TERM value like xterm instead, you'll get "line-noise" characters as the programs attempt to send formatting codes to a terminal emulator that isn't there.
You could probably get away with finding some termcap that was limited enough in capabilities that it won't bother you with noise too much, but if this is just to let you differentiate Emacs interactive shells from either Emacs non-interactive shells or non-Emacs interactive shells, there's a better choice.
This choice, in fact, isn't even sufficient. That's because this special shell script is loaded by both shell-mode and by TRAMP, so the above still wouldn't let you differentiate the two—you'd just get emacs in both cases instead of dumb!
So this is where the better choice comes in:
Using the INSIDE_EMACS environment variable
While, as you noted, the interactive shell and TRAMP both set TERM to dumb by default, they also set an environment variable INSIDE_EMACS.
Its existence (or not) alone is useful for your shell startup scripts, but its power for your use case lies in its value—which, for interactive (M-x shell) use, is something like 25.2.2,comint, but for TRAMP is 25.2.2,tramp.
So, to check for the three cases, here's what you can do (and what I personally have done myself in my ~/.zshrc for many years):
# Setup for all shells--Emacs or not, interactive or not, goes
# here
PATH=...
source $my_functions_file
# Now dumb terminals
if [[ "${TERM}" == "dumb" ]]; then
# Here put anything you want to run in any dumb terminal,
# even outside Emacs.
PATH=...
alias lsF='ls -F'
etc
# Now, just configs for shells inside Emacs
case ${INSIDE_EMACS/*,/} in
(comint)
do_comint_stuff
;;
(tramp)
do_tramp_stuff
;;
(term*)
# For M-x ansi-term, etc., you get a value like
# 25.2.2,term:0.96, but those shouldn't coincide with
# TERM being `dumb`, so warn....
echo "We somehow have a dumb Emacs terminal ${INSIDE_EMACS/*,/}" >&2
;;
("")
# Empty means we're $TERM==dumb but not in Emacs, do nothing
;;
(*)
# We shouldn't get here, so write a warning so we can
# figure out how else Emacs might be running a shell,
# but send it to stderr so that it won't break anything
echo "Something is wrong: INSIDE_EMACS is ${INSIDE_EMACS}" >&2
;;
esac
# finish shell setup for dumb now--the rest of the file will
# be skipped
return
fi
# Stuff for non-dumb, interactive visual, shells goes here
setup_prompt
setup_keybindings
etc
We don't reset TERM to a different value inside the case statement because dumb is exactly what it should be.
Note that above, in the (tramp) section of the case statement, you could do what you mentioned in your question—set TERM to something else just for TRAMP—but that would be a bad idea, since Emacs actually reads and acts on responses it gets from TRAMP shells, and the line noise would be an even bigger problem. TRAMP can do some really amazing things, but only when the shell output it's reading is in the format TRAMP expects.
(One final thing: using the code as above, with the INSIDE_EMACS checks nested instead the dumb terminal check, we don't have a single place to put code to be run in all Emacs-spawned shells regardless of type, including M-x ansi-term and its ilk. You could write a separate statement for that in your shell config... but that's exactly what ~/.emacs.d/init_${SHELLNAME}.sh is for, so probably a better choice if you need this for some reason.)

Bourne shell: how to redirect to multiple-digit fd?

In a C program I have a file descriptor (actual example: 14, but of course the program doesn't know this in advance) open for writing. I wish to call system(3) to run something and send its standard output to this file descriptor. Of course, this calls /bin/sh, which is the Bourne shell, which doesn't recognize constructs of the form 1>&14. Is there an alternative syntax (perhaps using braces or something) which I can use to let the Bourne shell see the 14 and use it? I could of course do one of these:
Do a fork/exec combo instead of system(3) and redirect by hand.
Redirect the output to a file and then copy the data therefrom to file descriptor 14.
Since I have root, have /bin/sh point to Bash.
The most elegant way would be to discover a syntax by which the Bourne shell will accept a multiple-digit file descriptor number. Is there such?
Consider my favorite rules about optimization: (1) Do not optimize. (2) For experts: do not optimize yet.
The situation arising in the question will (for me) arise in code which will be executed at most 100 times a day. So this will suffice:
sprintf(big_string,
"bash -c \"somethingsomething 1>&%d\"",
the_fd
);

how to read texts on the terminal inside perl script

Is there any way to capture the texts on termianl screen inside a perl script. I know there are some functions like system,exec,backticks but the problem is that they execute commands FROM the script.For ex:- in terminal i write cd/ (or) ls,and after that i run my perl script which will read what was written on termianl screen(in this case, scipt will capture cd/ (or) ls-whichever was given to termianl). I came with one solution that by passing the commands which you wrote on termianl as a command line arguments to the script,but any other way???
Like this maybe:
history | perl -ne 'print $_'
As I understand it, in a situation where you've typed some stuff into a terminal like this:
[tai#littlerobot ~] echo "Hello"
Hello
[tai#littlerobot ~] perl myscript.pl
You want myscript.pl to be able to access the echo "Hello" part, and possibly also the Hello that was that command's output.
Perl does not provide such a feature. No programming language does or can provide such a feature because the process in which your script/program runs has no intrinsic knowledge about what happened in the same terminal before it was run. The only way it could access this text would be if it could ask the currently running terminal, which will have some record of this information (i.e. the scrollback buffer), even if it cannot distinguish between which characters in the text were typed by you, and which are output. However, I know of no terminal that exposes that information via any kind of public API.
So if you want myscript.pl to be able to access that echo "Hello", you'll need to pass it to your script. Piping history to your script (as shown by Mark Setchell in his answer) is one technique. history is a shell built-in, so it has as much knowledge as your shell has (which is not quite the same knowledge as your terminal has). In particular it can give you a list of what commands have been typed in this shell session. However, it cannot tell you about the output generated by those commands. And it cannot tell you about other shell sessions, so doing this in Perl is fairly useless:
my #history = `tcsh -c history`;
The last thing you could try (though it would be incredibly complicated to do) would be to ask the X server (or Windows if running on that operating system) for a screen shot and then attempt to locate which rectangle the current terminal is running in and perform OCR on it. This would be fraught with problems though, such as dealing with overlapping windows.
So, in summary, you cannot do this. It's nothing to do with Perl. You cannot do this in any programming language.

VIM as a full-featured extensible IDE for any language

Hello I would like to master VIM as my primary IDE. I know there are many plugins etc. but I have one question: Is possible for VIM to understand the particular language (in case I wont plugin for my language) in which code is written? I mean some rules that I can define and then use e.g. for auto-completion, refactoring, folding etc. For example consider following two perl codes in which I want refactor variables. In first example there are variables with same names but one is scalar and another are array and hash, in second example same name of variable as was defined before was used in another scope (loop etc.). Thus refactoring using simple text matching is not elegant way I thing:
1st example:
my #same_name;
my $same_name; # How to refactor this variable without affecting all other variables?
my %same_name;
$same_name[0] = 5;
$same_name{"key"} = 5;
$same_name = 5;
2nd example:
my #array;
my $already_existing_variable; # How to refactor this variable
foreach my $already_existing_variable (#array){
print $already_existing_variable; # Without affecting this variable
}
print $already_existing_variable; # Variable that should be also refactorized
Or how can I achieve that when I type $arr {and hit TAB here} it will automatically extend to $array[ ? For this VIM must to know that when I prepend $ before variable which was declared with # I want to access array elements.
Another example would be: how to fold code using e.g. BEGIN and END keywords? Those was jut trivial examples but I think you get the point. I think it is similar task to write own compiler or something. Thank you.
I'm using vim with my perl scripts almost all days:
Rename variables
App::EditorTools gives you the function to rename variables like Padre.
install App::EditorTool $ cpanm App::EditorTools
install vim plugin $ editortools install-vim
move cursor on the variable name in vim.
type \pL
I'm not sure why it parses wrong scope in the 2nd example, but you can temporarily wrap the foreach brock with lambda and rename variables inside the code block first.
sub {
foreach my $already_existing_variable (#array){
print $already_existing_variable; # Without affecting this variable
}
}->();
Reformat script indent
Perl::Tidy has perltidy command line tool to format your script.
install Perl::Tidy $ cpanm Perl::Tidy
create ~/.perltidyrc according to your taste. like folowing:
-pbp
-pt=2
-sbt=2
-bt=2
-bbt=2
-ce
-nbbc
set equalprg to perltidy in your ~/.vimrc
au FileType perl setl ep=perltidy
type gg=G in your script.
Syntax Check
vim's built-in compiler plugin for perl does very well.
set :compilerto perl in your ~/.vimrc
au FileType perl :compiler perl
type :make in normal mode
type :copen to open up quickfix window
if you don't want warnings in your quickfix list, you can unset the flag for it.
let g:perl_compiler_force_warnings = 0
$PERL5LIB is also important while invoking :make, you can give specific directories in it.
let &l:path = './lib,./blib/lib,./blib/arch,' . &l:path
let $PERL5LIB = substitute(&l:path, ',', ':', 'g')
Completions
vim has nice completion tool out of the box. see :help comple-generic
type $ar in insert mode and press CTRL-N
You might be interested in ctags too.
I can already tell something is wrong when the first sentence is "Hello I would like to master VIM as my primary IDE."
Vim is not an IDE. Vim is a text editor. (You can use google to find out more)
If you feel that the features an IDE provides (refactoring, smarter auto-completion...) are more important than the features that vim provides (fast movement, never take your hands off the home row, programmable editor...) then you should use an IDE, or an IDE with a vim plugin. Usually, if you want to mix IDE features with vim features, you do it with a plugin to the IDE, not the other way around (there are some exceptions such as eclim).