Cygwin shortcut for command history - command-line

How can I search the command history in cygwin?
I don't want to keep pressing the arrow keys to execute a command from console command history.

If you are using the default editing mode, do ctrl+R to search back through your history.
If you have done set -o vi to use vi editing mode, then it is esc-/

The history command is the way to go. I use
h ()
{
history | cut -f 2- | sort -u | grep -P --color=auto -e "$*"
}
so that I can type something like h git.*MyProgram, h ^tar -c, h svn:ignore, etc to pull up a sorted list of past commands matching a regex.
You might also want to add the following lines to ~/.inputrc:
# Ctrl+Up/Down for searching command history
"\e[1;5A": history-search-backward
"\e[1;5B": history-search-forward
With these in place, you can type a partial command prefix (such as gi or sql) then use Ctrl+Up to scroll back through the list of just your command history entries that match that prefix (such as git clone https://code.google.com/p/double-conversion/ and sqlite3 .svn/wc.db .tables). This can be a lot faster than searching and then cutting and pasting if you want to edit or re-execute a command that was fairly recent.

I use the history command in combination with grep, e.g. history | grep vi shows all commands where vi was used.

Checkout the "Gnu Bash Manual" (man bash) for the command "fc". E.g.fc -l -80 would list the last 80 commands, while other options let you search with RegEx...

Do
vi ~/.inputrc
Add
For arrow up/down bindings:
"\e[A": history-search-backward
"\e[B": history-search-forward
Or for page up/down bindings:
"\e[5~": history-search-backward
"\e[6~": history-search-forward
Close and open cygwin.
Voila.

I think one of the easiest way is to pipeline it with less and press search character ("/") and then type the command you wanna find.
history | less
and then
/text to find
to find the desired command
Another way
is to append the stdout form history command to a file: history > /cygdrive/path/file.txt
and then search in the document.

Related

How to get vim to list the PIDs of selected files that are presently being edited, avoiding recovery mode, and not list all the other files

The vim manual page contains two similar -r type commands. I'll give more background below, this question is really how to invoke the first type of -r to list the swap files, but avoid the second -r that invokes recovery
-r List swap files, with information about using them for re‐
covery.
-r {file} Recovery mode. The swap file is used to recover a crashed
editing session. The swap file is a file with the same
filename as the text file with ".swp" appended. See ":help
recovery".
The -r without filename (the first -r above ) reports on the swap files of other files too, including ones in other directories
Background:
I'm trying to have vim report the swap files of a specific file (mostly to determine if vim still editing the file). If the file is being edited ( in another window, either on linux or cygwin ) I can 'raise' that window up to the top with "\e[2t\e[1t" as I have successfully be able to do thanks to Bring Window to Front
Vim has multiple swap file names, and multiple directories that it could put a file, so I want to ask vim, please tell me the name of the swap files that are currently in use for a given file, and if there is a current vim process on the file. Unfortunately, sometimes vim will open a command file in recovery mode in unexpected ways.
I'm invoking vim like this vim -r -c :q file, well actually, I'm invoking it from script, since I want vim to see something more like a terminal, then I look at the output file, so it's more like script -q -c "vim -r -c :q foo" fooscript, then I look in the fooscript file for messages like /Note: process STILL RUNNING: (\d+)/
It is beginning to look like I need to use vim -r without a file name, and parse the output of the -r report, and that there isn't a way to get the report pre-filtered to a single file in question.
after switching my focus to just vim -r, and
Knowing that vim will try to put the swap file into the same directory as the file it's editing ( thanks to #romainl for the pointer to :help swap-file )
observing that vim -r reports on the files in the current directory first,
observing that the file name associated with the swap file is reported before the process id of the vim process, and
observing that vim appends (STILL RUNNING) if it finds the active process
I changed the current directory appropriately and ran this code after plugging in the name of the file-to-search-for
perl -lne '
last if /^\s+In directory/;
undef $f if /^\d+/;
$f = $1 if /^\s+file name:\s+(.*)\s*$/;
if ( $f =~ m#/file-to-search-for# && /^\s+ process ID:\s(\d+).*?STILL RUNNING/ ) {
print $1;
$pid //= $1;
}
END { exit !$pid; } '
The pid of the running vim process is printed, and the exit status is zero when the appropiate swap file is found, and non-zero if the file was not being edited

How can I convert indentation between spaces and tabs for all files in a workspace in a single action?

How can I use VS Code's Convert Indentation To Spaces or Convert Indentation to Tabs commands on all the files in my workspace in a single action instead of using the command for each file?
I'm not aware of a way to do this with VS Code (at least- not without extensions, and I don't know of any such extensions offhand).
But if you're on a posix system (not sure if I'm using "posix" right here), you can do this via command line using a modified version of this:
git ls-files | command grep -E '*.ts$' | awk '{print "expand --tabs=4 --first-only", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh
The above command lists all files tracked in the git repo for the current working directory, filters for files with the .ts extension, and then uses awk and expand to replace leading indentation of a tabs to a specified number of spaces.
To go from spaces to tabs, use the unexpand command instead.
If you're not working with a git repo, you can replace git ls-files with find -type f (the advantage of git ls-files is that it won't touch anything that's not tracked).
Just change the regular expression in the grep filter to whatever you need.
The command replaces leading groups of 4 spaces with tab characters. Just change the --tabs argument to the unexpand command with whatever number of spaces your indentation is.

Add text to the top of multiple files in emacs

I'd like to add a couple lines of text (copyright) to the top of all text files in a directory. Can I do this in emacs without copy/pasting for each file?
This is copied from Chris Conway's answer to a different question: Using Emacs to recursively find and replace in text files not already open
M-x find-name-dired: you will be prompted for a root directory and a filename pattern.
Press t to "toggle mark" for all files found.
Press Q for "Query-Replace in Files...": you will be prompted for query/substitution regexps.
Proceed as with query-replace-regexp: SPACE to replace and move to next match, n to skip a match, etc.
You can use it the same way
Yes, with
find . -type f -exec emacs -batch '{}' --eval '(insert-string "foo\nbar\nbaz\n")' -f save-buffer \;
or something to that effect. The emacs bit is
emacs -batch filename --eval '(insert-string "foo\nbar\nbaz\n")' -f save-buffer
replace "foo\nbar\nbaz" with your message. However, using emacs for this is really a lot of overkill. You could just put your copyright header into a file and use cat header file > tempfile; mv tempfile file.

Using grep in eshell on NTemacs

I have been trying to do a recursive grep command on files in sub folders using grep in NTemacs and Cygwin. So far the "best" results have been using grep in eshell. When I use this:
grep "t" -r *
I get a list of all file names containing the letter t, in all sub folders one layer down but notthing else. In Cygwin i get nothing. I'm working on a directroy that is not in the Cygwin install. Don't know if that mather or not.
What I want is to match the content of a more complex string in all files (and not just the file names, but the content). And in all sub directories.
I would like to use eshell from emacs but I'm open to suggestions, apart form using LINUX. This is a work PC and I don't want to do all the setup of a LINUX install.
i just wrote a very similar answer to another question, but i suspect it's the same root problem:
my first thought is that your files have windows line endings (CRLF) as opposed to unix/linux line endings (LF), and that is messing with grep's ability to parse the file. try running this:
dos2unix filename
on each file you need to search then try your grep statement again.
if you need to convert many files across several directories, i suggest using dos2unix with the -exec action of find:
find . -exec dos2unix {} \;
(add whatever other options you need to find before running that, of course)

Unable to use SED to edit files fast

The file is initially
$cat so/app.yaml
application: SO
...
I run the following command. I get an empty file.
$sed s/SO/so/ so/app.yaml > so/app.yaml
$cat so/app.yaml
$
How can you use SED to edit the file and not giving me an empty file?
$ sed -i -e's/SO/so/' so/app.yaml
The -i means in-place.
The > used in piping will open the output file when the pipes are all set up, i.e. before command execution. Thus, the input file is truncated prior to sed executing. This is a problem with all shell redirection, not just with sed.
Sheldon Young's answer shows how to use in-place editing.
You are using the wrong tool for the job. sed is a stream editor (that's why it's called sed), so it's for in-flight editing of streams in a pipe. ed OTOH is a file editor, which can do everything sed can do, except it works on files instead of streams. (Actually, it's the other way round: ed is the original utility and sed is a clone that avoids having to create temporary files for streams.)
ed works very much like sed (because sed is just a clone), but with one important difference: you can move around in files, but you can't move around in streams. So, all commands in ed take an address parameter that tells ed, where in the file to apply the command. In your case, you want to apply the command everywhere in the file, so the address parameter is just , because a,b means "from line a to line b" and the default for a is 1 (beginning-of-file) and the default for b is $ (end-of-file), so leaving them both out means "from beginning-of-file to end-of-file". Then comes the s (for substitute) and the rest looks much like sed.
So, your sed command s/SO/so/ turns into the ed command ,s/SO/so/.
And, again because ed is a file editor, and more precisely, an interactive file editor, we also need to write (w) the file and quit (q) the editor.
This is how it looks in its entirety:
ed -- so/app.yaml <<-HERE
,s/SO/so/
w
q
HERE
See also my answer to a similar question.
What happens in your case, is that executing a pipeline is a two-stage process: first construct the pipeline, then run it. > means "open the file, truncate it, and connect it to filedescriptor 1 (stdout)". Only then is the pipe actually run, i.e. sed is executed, but at this time, the file has already been truncated.
Some versions of sed also have a -i parameter for in-place editing of files, that makes sed behave a little more like ed, but using that is not advisable: first of all, it doesn't support all the features of ed, but more importantly, it is a non-standardized proprietary extension of GNU sed that doesn't work on many non-GNU systems. It's been a while since I used a non-GNU system, but last I used one, neither Solaris nor OpenBSD nor HP-UX nor IBM AIX sed supported the -i parameter.
I believe that redirecting output into the same file you are editing is causing your problem.
You need redirect standard output to some temporary file and when sed is done overwrite the original file by the temporary one.