Alias ​to open a file by name - zsh

Aliases allow you to open certain file formats simply by typing the filename in a terminal. For example, if the file is of type html, htm, it will open in firefox. alias -s {html,htm}=firefox
I could do the same for text files and just list the types I want, but what if the file doesn't have them, like ~/.zshrc or /etc/fstab? How can I open such a file by name?

This function should do what you want (add it to .zshrc):
command_not_found_handler() {
if [[ -o interactive && -w $1 ]]; then
vi $1
else
echo zsh command_not_found_handler: command not found: $# >&2
return 1
fi
}
As the name indicates, this is called whenever zsh is unable to find a command entered in the shell. Now, if a 'command' isn't found, the editor will be invoked on that argument.
The -o interactive test should ensure that the editor is only called when you've typed something in; an invalid command in a shell script will still fail. The -w test checks for editable files.
You may find other conditions to check as you use this.
ETA: As noted in the comments, this only works with simple file names; it will not work if the path to the file is specified.

For common files you edit frequently you can make individual aliases for those files. I have aliases for
alias hosts="sudo vi /etc/hosts"
alias zshrc="vi ~/.zshrc"

Related

Why does the alias I have created not execute in the path I am expecting?

I have created an alias that is intended to copy to my clipboard whichever path I am in, in the terminal.
The alias is in my .zshrc file.
The alias looks as follows:
alias cpath="echo -n `pwd`|pbcopy"
When I execute the following command in my terminal it always works:
echo -n `pwd`|pbcopy
However, when I use the alias cpath, it copies whichever path was the path when I first opened a particular terminal. For example, if I open a terminal in the /Users/tommyrharper directory, then I run cpath, it will copy the following path to my clipboard: /Users/tommyrharper.
If I then cd into my Documents folder, then run cpath, then it will still just add /Users/tommyrharper to my clipboard.
However If I then directly run echo -n `pwd`|pbcopy it will add /Users/tommyrharper/Documents to my clipboard.
If I initially opened a terminal in /Users/tommyrharper/Documents and then I run cpath, then it will add /Users/tommyrharper/Documents to my clipboard.
But then again if I cd into my Notes directory, then I run cpath, it will still just add /Users/tommyrharper/Documents to my clipboard.
Why is my alias not behaving in the same way as when I directly enter the command in the terminal?
And is there a way to get my alias to work as expected?
This happens because the backtick command substitution in your alias (`pwd`) gets run when zsh sources .zshrc when it starts up. This is because you have used doubles quotes, which evaluate substitutions.
You can confirm this by running alias cpath, which will display the definition of the alias, which should now include a path instead of a literal `pwd`.
If you instead define your alias like this with single quotes (which do not evaluate substitutions):
alias cpath='echo -n `pwd`|pbcopy'
it will work as expected.
More details on the different quoting styles and substitutions can be found here: https://mywiki.wooledge.org/Quotes

Change Location of zcompdump Files

Is it possible to change the location of .zcompdump and .zhistory files generated by ZSH?
They are polluting my Home Directory.
One possible solution I found was changing the value of $ZDOTDIR to $HOME/.config/zsh. I did the following, but it does not seem to work (temp files are still created in the home directory).
$ cat ~/.zshenv
ZDOTDIR=$HOME/.zsh
. $ZDOTDIR/.zshenv
.zcompdump files are produced to speed up the running of compinit, Which initializes the shell completion in zsh. You could specify an explicit dump file by compinit -d <dumpfile> in your .zshrc to change the location where compdump are stored.
Change the value for HISTFILE to set different location to store you zsh command history.
$ man zshall
/Use of compinit
To speed up the running of compinit, it can be made to produce a dumped
configuration that will be read in on future invocations; this is the
default, but can be turned off by calling compinit with the option -D. The
dumped file is .zcompdump in the same directory as the startup files (i.e.
$ZDOTDIR or $HOME); alternatively, an explicit file name can be given by
`compinit -d dumpfile'. The next invocation of compinit will read the
dumped file instead of performing a full initialization.

How do I add more words to an existing Aspell dictionary?

I have installed Aspell dictionary to spell check my document. But in the document there are some words which are spelled incorrectly but I do not want aspell to detect those as incorrect. So, basically I want to add those words to the existing aspell dictionary.
I am trying to follow instructions given here: http://wiki.zimbra.com/wiki/Adding_words_to_existing_aspell_dictionaries but I am not able to understand the commands given here and also where to type these commands. I tried executing these commands on command prompt but I keep getting errors regarding directory. This is what I am trying on command prompt.
My Aspell program's path is C:/Program Files (x86)/Aspell/
C:\Program Files (x86)>/Aspell/bin/./aspell --lang=en create master yourl
ist.rws < C:/Users/admin/Desktop/yourlist.txt
The system cannot find the path specified.
C:\Program Files (x86)>
Please tell me what am I doing wrong? I have not worked before on command prompt.
Also if there is any other easier alternative (like doing so form R GUI) please suggest that too.
I know this thread is old and it's about Windows, but I was having trouble with getting this to work on Linux and this thread was one of the only search result that came up and it has no answer. So while this doesn't answer the exact question, I wrote a script that allows you to add a word to a dictionary that hopefully will help some people.
First, run the following command to determine what your default dictionary name is:
$ aspell dump config | grep "default: <lang>"
Then in a new file (I named mine addword):
#!/bin/bash
# This should be whatever your path to your aspell directory is
ASPELL_DIR=/usr/lib/aspell-0.60
# Make sure to change this to the proper dictionary name
ENGLISH_DICT="$ASPELL_DIR/<your-default-dictionary>.multi"
# And name this to the filename you want for your dictionary
MY_DICT_NAME="my-dict"
# then the directory path to that file
MY_DICT_SRC="/path/to/dict/$MY_DICT_NAME.txt"
MY_DICT_DEST="$ASPELL_DIR/$MY_DICT_NAME.rws"
if [ "$EUID" -ne 0 ]; then
echo "You must execute this script as root."
exit -1;
fi
if [ $# -eq 0 ]; then
echo "No arguments supplied"
else
if ! grep -q "$MY_DICT_NAME.rws" "$ENGLISH_DICT" ; then
echo "add $MY_DICT_NAME.rws" >> "$ENGLISH_DICT"
echo "Adding $MY_DICT_DEST to $ENGLISH_DICT"
fi
echo "$1" >> "$MY_DICT_SRC"
echo "Adding '$1' to English dictionary $MY_DICT_SRC"
sudo aspell --lang=en create master "$MY_DICT_DEST" < "$MY_DICT_SRC"
fi
And then running
sudo addword aragorn
will add the word "aragorn" to your default dictionary.
I know this thread was long dead, but thought this might be useful!

Permissions when iterating over files in directory Unix TCSH scripting

I'm writing a script that will print the file names of every file in a subdirectory of my home directory. My code is:
foreach file (`~/.garbage`)
echo "$file"
end
When I try to run my script, I get the following error:
home/.garbage: Permission denied.
I've tried setting permissions to 755 for the .garbage directory and my script, but I can't get over this error. Is there something I'm doing incorrectly? It's a tcsh script.
Why not just use ls ~/.garbage
or if you want each file on a separate line, ls -1 ~/.garbage
backtic will try to execute whatever is inside them. You are getting this error since you are giving a directory name within backtic.
You can use ls ~/.garbage in backtics as mentioned by Mark or use ~/.garbage/* in quotes and rely on the shell to expand the glob for you. If you want to get only the filename from a full path; use the basename command or some sed/awk magic

`(cd X; pwd)` sometimes returns two-line

I have shell script which starts with:
sdir=`dirname $0`
sdir=`(cd "$sdir/"; pwd)`
And this usually gets expanded (with 'sh -h') into
++ dirname /opt/foo/bin/bar
+ sdir=/opt/foo/bin
++ cd /opt/foo/bin/
++ pwd
+ sdir=/opt/foo/bin
but for single user for single combination of parameters in expands into (note two lines at the result sbin value)
++ dirname bin/foo
+ sdir=bin
++ cd bin/
++ pwd
+ sdir='/opt/foo/bin
/opt/foo/bin'
I tried different combinations but was not able to reproduce this behavior. With different input parameters for that user it started producing correct single line result. I am new to shell scripting, so please advice when such (cd X; pwd) can return two line.
it was observed on CentOS, but not sure it that matters. Please advice.
The culprit is cd, try this instead
sdir=`dirname $0`
sdir=`(cd "$sdir/" >/dev/null; pwd)`
This happens because when you specify a non absolute path and the directory is found in the environment variable CDPATH, cd prints to stdout the value of the absolute path to the directory it changed to.
Relevant man bash sections:
CDPATH The search path for the cd command. This is a
colon-separated list of directories in which the
shell looks for destination directories specified
by the cd command. A sample value is ``.:~:/usr''.
cd [-L|-P] [directory]
Change the current working directory to directory. If
directory is not given, the value of the HOME shell
variable is used. If the shell variable CDPATH exists,
it is used as a search path. If directory begins with a slash,
CDPATH is not used.
The -P option means to not follow symbolic links; symbolic
links are followed by default or with the -L option. If
directory is ‘-’, it is equivalent to $OLDPWD.
If a non-empty directory name from CDPATH is used, or if ‘-’
RELEVANT -\ is the first argument, and the directory change is successful,
PARAGRAPH -/ the absolute pathname of the new working directory is written
to the standard output.
The return status is zero if the directory is successfully
changed, non-zero otherwise.
OLDPWD The previous working directory as set by the cd
command.
CDPATH is a common gotcha. You can also use "unset CDPATH; export CDPATH" to avoid the problem in your script.
It's possible that user has some funky alias for "cd". Perhaps you could try making it do "/usr/bin/cd" (or whatever "cd" actually runs by default) instead.
Some people alias pwd to "echo $PWD". Also, the pwd command itself can either be a shell built-in or a program in /usr/bin. Do an "alias pwd" and "which pwd" on both that user and any user that works normally.
Try this:
sdir=$( cd $(dirname "$0") > /dev/null && pwd )
It's just a single line and will keep all special characters in the directory name intact. Remember that on Unix, only two characters are illegal in a file/dir name: 0-byte and / (forward slash). Especially, newlines are valid in a file name!

Resources