line breaks.
This commit is contained in:
		
							parent
							
								
									3017160c46
								
							
						
					
					
						commit
						bc251f8790
					
				
					 2 changed files with 82 additions and 103 deletions
				
			
		| 
						 | 
					@ -124,51 +124,45 @@ Ive noticed that people are rethinking and reinventing tools that have existed s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## The lessons learned from the past
 | 
					## The lessons learned from the past
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A large amount of the innovation in the area, I think, can be attributed to
 | 
					A large amount of the innovation in the area, I think, can be attributed to lessons that have been learned in 50 years of using software;
 | 
				
			||||||
lessons that have been learned in 50 years of using software; sharp edges we
 | 
					sharp edges we have repeatedly cut ourselves on,
 | 
				
			||||||
have repeatedly cut ourselves on, unintuitive interfaces that repeatedly trip us
 | 
					unintuitive interfaces that repeatedly trip us up,
 | 
				
			||||||
up, and growing frustration at the limitations that maintaining decades of
 | 
					and growing frustration at the limitations that maintaining decades of backwards compatibility imposes on our tools.
 | 
				
			||||||
backwards compatibility imposes on our tools.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
These lessons have been gathering in the collective conciousness, through
 | 
					These lessons have been gathering in the collective conciousness;
 | 
				
			||||||
cheatsheets, guides, and FAQs; resources to guide us through esoteric error
 | 
					through cheatsheets, guides, and FAQs;
 | 
				
			||||||
messages, complex configurations, and dozens upon dozens of flags.
 | 
					resources to guide us through esoteric error messages, complex configurations, and dozens upon dozens of flags.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Id like to go over a couple of the more prominent lessons that I feel terminal
 | 
					Id like to go over a couple of the more prominent lessons that I feel terminal tools have learned in the past several decades.
 | 
				
			||||||
tools have learned in the past several decades.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### A good out of the box experience
 | 
					### A good out of the box experience
 | 
				
			||||||
 | 
					
 | 
				
			||||||
While configurability is great, one should not need to learn a new configuration
 | 
					While configurability is great,
 | 
				
			||||||
language and dozens or hundreds of options to get a usable piece of software.
 | 
					one should not need to learn a new configuration language and dozens or hundreds of options to get a usable piece of software.
 | 
				
			||||||
Configuration should be for customization, not setup.
 | 
					Configuration should be for customization, not setup.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
One of the earliest examples of this principle may be the fish shell.
 | 
					One of the earliest examples of this principle may be the fish shell.
 | 
				
			||||||
Both zsh and fish have powerful prompt and autocompletion engines, but zsh
 | 
					Both zsh and fish have powerful prompt and autocompletion engines,
 | 
				
			||||||
requires you to setup a custom prompt and enable completions in order to use the
 | 
					but zsh requires you to setup a custom prompt and enable completions in order to use the features that set it apart from the competition.
 | 
				
			||||||
features that set it apart from the competition. With no config file, zsh is no
 | 
					With no config file, zsh is no better than bash.
 | 
				
			||||||
better than bash. When starting fish for the first time, however, its powerful
 | 
					When starting fish for the first time however,
 | 
				
			||||||
autocompletion and information rich prompt are front and center with no
 | 
					its powerful autocompletion and information rich prompt are front and center with no configuration required.
 | 
				
			||||||
configuration required. Of course, fish still has the same level of
 | 
					Of course, fish still has the same level of configurability as zsh, it just also has sensible defaults.
 | 
				
			||||||
configurability as zsh, it just also has sensible defaults.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
To demonstrate my point, this is the default prompt for zsh with no
 | 
					To demonstrate my point, this is the default prompt for zsh with no configuration.
 | 
				
			||||||
configuration. It *only* shows the hostname, none of the advanced featurs you
 | 
					It *only* shows the hostname, none of the advanced featurs you can get out of a zsh prompt even without plugins.
 | 
				
			||||||
can get out of a zsh prompt even without plugins.
 | 
					 | 
				
			||||||

 | 
					
 | 
				
			||||||
Here is bash's prompt. It actually gives more info than zsh's, even though zsh
 | 
					Here is bash's prompt.
 | 
				
			||||||
can do more when properly configured.
 | 
					It actually gives more info than zsh's, even though zsh can do more when properly configured.
 | 
				
			||||||

 | 
					
 | 
				
			||||||
And here is fish's default prompt. It has a few colours, shows everything the
 | 
					And here is fish's default prompt.
 | 
				
			||||||
bash prompt does, and additionally shows the git branch we are on.
 | 
					It has a few colours, shows everything the bash prompt does, and additionally shows the git branch we are on.
 | 
				
			||||||

 | 
				
			||||||
info](fish_prompt.png)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Text editors are another great example of the evolution of out of the box
 | 
					Text editors are another great example of the evolution of out of the box defaults.
 | 
				
			||||||
defaults. Vim and Neovim both improved on their predecessors, but so much of
 | 
					Vim and Neovim both improved on their predecessors,
 | 
				
			||||||
that improvement is locked behind extremely complex configuration experiences
 | 
					but much of that improvement is locked behind extremely complex configuration experiences and plugins.
 | 
				
			||||||
and plugins. Heres four different terminal text editors with no configuration
 | 
					Heres four different terminal text editors with no configuration applied:
 | 
				
			||||||
applied:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||

 | 
					configuration](editors.png)
 | 
				
			||||||
| 
						 | 
					@ -177,33 +171,26 @@ Vi, (top left) is our baseline, and, as far as I can tell, doesnt actually
 | 
				
			||||||
support much for configuration. What you see out of the box is more or less
 | 
					support much for configuration. What you see out of the box is more or less
 | 
				
			||||||
whats there.
 | 
					whats there.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vim (top right) greatly improved on Vi, adding things such as syntax highlighting, line
 | 
					Vim (top right) greatly improved on Vi, adding things such as syntax highlighting, line numbers, spellchecking, split windows, folding, and even basic autocompletion.
 | 
				
			||||||
numbers, spellchecking, split windows, folding, and even basic autocompletion.
 | 
					However, everything but syntax highligting is either extremely clunky or outright disabled without configuration.
 | 
				
			||||||
However, everything but syntax highligting is either extremely clunky or
 | 
					(for example, the earliest things I did when I first made a `.vimrc` was to enable indent folding,
 | 
				
			||||||
outright disabled without configuration. (for example, the earliest things I did
 | 
					make some better keybinds for navigating windows, and adding a line number ruler to the side)
 | 
				
			||||||
when I first made a `.vimrc` was to enable indent folding, make some better
 | 
					 | 
				
			||||||
keybinds for navigating windows, and adding a line number ruler to the side)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Neovim (bottom left) further improved on Vim, adding support for Treesitter and
 | 
					Neovim (bottom left) further improved on Vim, adding support for Treesitter and the Language Server Protocoll, but the out of the box experience is the *exact* same as vim!
 | 
				
			||||||
the Language Server Protocoll, but the out of the box experience is the *exact*
 | 
					In order to take advantage of the LSP and Treesitter support, you have to install plugins,
 | 
				
			||||||
same as vim! In order to take advantage of the LSP and Treesitter support, you
 | 
					which means learning a Nvim package manager, learning how to configure LSPs, and configuring a new LSP for every language you want to use it with.
 | 
				
			||||||
have to install plugins, which means learning a Nvim package manager, learning
 | 
					(Or finding out about Mason and being OK with having multiple levels of package management in your Nvim install alone).
 | 
				
			||||||
how to configure LSPs, and configuring a new LSP for every language you want to
 | 
					Dont get me wrong, Neovim is a great editor once you get over the hump, I still use it as my daily driver, but so much of its functionality is simply hidden.
 | 
				
			||||||
use it with. (Or finding out about Mason and being OK with having multiple
 | 
					 | 
				
			||||||
levels of package management in your Nvim install alone). Dont get me wrong,
 | 
					 | 
				
			||||||
Neovim is a great editor once you get over the hump, I still use it as my daily
 | 
					 | 
				
			||||||
driver, but so much of its functionality is simply hidden.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Then we have the Helix (bottom right) editor. Colour scheme aside, everything is
 | 
					Then we have the Helix (bottom right) editor. Colour scheme aside, everything is just there.
 | 
				
			||||||
just there. Helix doesnt have plugin support
 | 
					Helix doesnt have plugin support [yet](https://github.com/helix-editor/helix/discussions/3806),
 | 
				
			||||||
[yet](https://github.com/helix-editor/helix/discussions/3806), but it has so
 | 
					but it has so much stuff in core that,
 | 
				
			||||||
much stuff in core that, looking through my neovim plugins, pretty much all of
 | 
					looking through my neovim plugins,
 | 
				
			||||||
them are in the core editor! (ironically, the one feature that I feel helix is
 | 
					pretty much all of them are in the core editor!
 | 
				
			||||||
missing, [folding](https://github.com/helix-editor/helix/issues/1840), is a core
 | 
					(ironically, the one feature that I feel helix is missing, [folding](https://github.com/helix-editor/helix/issues/1840),
 | 
				
			||||||
part of neovim, albiet one that requires some configuration to get good use out
 | 
					is a core part of neovim, albiet one that requires some configuration to get good use out of).
 | 
				
			||||||
of). Helix does have a config file where you can change a huge amount of
 | 
					Helix does have a config file where you can change a huge amount of settings,
 | 
				
			||||||
settings, but its an extremely usable IDE out of the box, thanks to having all
 | 
					but its an extremely usable IDE out of the box, thanks to having all of its features enabled by default.
 | 
				
			||||||
of its features enabled by default.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Friendly error messages
 | 
					### Friendly error messages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,7 @@ You can sort, filter, and aggregate the data,
 | 
				
			||||||
use a SQL style join statement between two tables,
 | 
					use a SQL style join statement between two tables,
 | 
				
			||||||
and use functional programming patterns to manipulate tables.
 | 
					and use functional programming patterns to manipulate tables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some examples of things that nushell enables with this structured data passing
 | 
					Some examples of things that nushell enables with this structured data passing through pipelines includes:
 | 
				
			||||||
through pipelines includes:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
# show all files recursively that were modified in the last week
 | 
					# show all files recursively that were modified in the last week
 | 
				
			||||||
| 
						 | 
					@ -123,26 +122,23 @@ update bytes_sent {into int}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
(each line has a comment explaining what it does, for those unfamiliar with the nushell language)
 | 
					(each line has a comment explaining what it does, for those unfamiliar with the nushell language)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now that we have it in nushell tables, we can bring all of nushells tools to
 | 
					Now that we have it in nushell tables, we can bring all of nushells tools to bear on the data.
 | 
				
			||||||
bear on the data. For example, we could plot a histogram of the most common
 | 
					For example, we could plot a histogram of the most common ips, just by piping the whole thing into `histogram ip`.
 | 
				
			||||||
ips, just by piping the whole thing into `histogram ip`. We could easily
 | 
					We could easily calculate the average bytes sent per request.
 | 
				
			||||||
calculate the average bytes sent per request. We could group the records by the
 | 
					We could group the records by the day or hour they happened, and analyze each of those groups independently.
 | 
				
			||||||
day or hour they happened, and analyze each of those groups independently. And
 | 
					And we can do all of that after arbitrarily filtering, sorting, or otherwise transforming the table.
 | 
				
			||||||
we can do all of that after arbitrarily filtering, sorting, or otherwise
 | 
					 | 
				
			||||||
transforming the table.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
While it would be a pretty long one liner if we decided to put it in a single
 | 
					While it would be a pretty long one liner if we decided to put it in a single line,
 | 
				
			||||||
line, its still quite easy and straightforward to write.
 | 
					its still quite easy and straightforward to write.
 | 
				
			||||||
Most log formats and command outputs are similarly straightforward.
 | 
					Most log formats and command outputs are similarly straightforward.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Defining custom commands, with built-in arg parsing
 | 
					## Defining custom commands, with built-in arg parsing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Nushell has a feature called Custom Commands, which fill the same purpose as
 | 
					Nushell has a feature called Custom Commands,
 | 
				
			||||||
functions in other shells/programming languages, but are a bit more featurefull
 | 
					which fill the same purpose as functions in other shells/programming languages,
 | 
				
			||||||
than traditional POSIX shell functions.
 | 
					but are a bit more featurefull than traditional POSIX shell functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First of all, nushell custom commands specify the number of positional arguments
 | 
					First of all, nushell custom commands specify the number of positional arguments they take.
 | 
				
			||||||
they take.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
def recently-modified [cutoff] {
 | 
					def recently-modified [cutoff] {
 | 
				
			||||||
| 
						 | 
					@ -168,8 +164,8 @@ def recently-modified [cutoff: string] {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can give the arguments a default value, making it optional, (can be combined
 | 
					You can give the arguments a default value, making it optional.
 | 
				
			||||||
with a type specification)
 | 
					(can be combined with a type specification)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
def recently-modified [cutoff = '1 week ago'] {
 | 
					def recently-modified [cutoff = '1 week ago'] {
 | 
				
			||||||
| 
						 | 
					@ -181,9 +177,8 @@ def recently-modified [cutoff = '1 week ago'] {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You have flag parsing, complete with short flags, is included as well. (A
 | 
					You have flag parsing, complete with short flags, is included as well.
 | 
				
			||||||
flag without a type will be taken as a boolean flag, set by its presence or
 | 
					(A flag without a type will be taken as a boolean flag, set by its presence or absence)
 | 
				
			||||||
absence)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
def recently-modified [cutoff: string = '1 week ago' --older-than (-o)] {
 | 
					def recently-modified [cutoff: string = '1 week ago' --older-than (-o)] {
 | 
				
			||||||
| 
						 | 
					@ -203,8 +198,8 @@ def recently-modified [cutoff: string = '1 week ago' --older-than (-o)] {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
And finally, you can add a rest command at the end, allowing you to take a variable number of
 | 
					And finally, you can add a rest command at the end, allowing you to take a variable number of arguments.
 | 
				
			||||||
arguments.
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
def recently-modified [--cutoff = '1 week ago' ...paths] {
 | 
					def recently-modified [--cutoff = '1 week ago' ...paths] {
 | 
				
			||||||
    for $path in $paths {
 | 
					    for $path in $paths {
 | 
				
			||||||
| 
						 | 
					@ -217,8 +212,8 @@ def recently-modified [--cutoff = '1 week ago' ...paths] {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
All of the specified parameters are automatically added to a generated `--help`
 | 
					All of the specified parameters are automatically added to a generated `--help` page,
 | 
				
			||||||
page, along with a documentation comments, so that the following code block:
 | 
					along with a documentation comments, so that the following code block:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh>}}
 | 
					{{<highlight sh>}}
 | 
				
			||||||
# display recently modified files
 | 
					# display recently modified files
 | 
				
			||||||
| 
						 | 
					@ -260,13 +255,11 @@ Input/output types:
 | 
				
			||||||
  ╰───┴───────┴────────╯
 | 
					  ╰───┴───────┴────────╯
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(the input/output table at the bottom has to do with how the command is used in
 | 
					(the input/output table at the bottom has to do with how the command is used in a pipeline,
 | 
				
			||||||
a pipeline, and is covered in more detail in the
 | 
					and is covered in more detail in the [book](https://www.nushell.sh/book/command_signature.html))
 | 
				
			||||||
[book](https://www.nushell.sh/book/command_signature.html))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This addition of easy argument parsing makes it incredibly convenient to add
 | 
					This addition of easy argument parsing makes it incredibly convenient to add command line arguments to your scripts and functions,
 | 
				
			||||||
command line arguments to your scripts and functions, something that is anything
 | 
					something that is anything but easy in POSIX shells.
 | 
				
			||||||
but easy in POSIX shells.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Error messages
 | 
					## Error messages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,8 +289,8 @@ done
 | 
				
			||||||
(standard_in) 1: syntax error
 | 
					(standard_in) 1: syntax error
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This error tells you nothing about what went wrong, and your only option is to
 | 
					This error tells you nothing about what went wrong,
 | 
				
			||||||
start print debugging.
 | 
					and your only option is to start print debugging.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The equivalent in nushell would be:
 | 
					The equivalent in nushell would be:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -305,8 +298,9 @@ The equivalent in nushell would be:
 | 
				
			||||||
> ls | get size | each {|item| $item / 1000}
 | 
					> ls | get size | each {|item| $item / 1000}
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If we typo the size column, we get a nice error telling us exactly what we got
 | 
					If we typo the size column, we get a nice error telling us exactly what we got wrong,
 | 
				
			||||||
wrong, and where in the pipeline the error and value originated. Much better.
 | 
					and where in the pipeline the error and value originated.
 | 
				
			||||||
 | 
					Much better.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{<highlight sh "linenos=false">}}
 | 
					{{<highlight sh "linenos=false">}}
 | 
				
			||||||
> ls | get szie | each {|item| $item / 1000}
 | 
					> ls | get szie | each {|item| $item / 1000}
 | 
				
			||||||
| 
						 | 
					@ -325,8 +319,8 @@ Error: nu::shell::column_not_found
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now, nushell is not finished yet.
 | 
					Now, nushell is not finished yet.
 | 
				
			||||||
As I write, I am running version 0.91 of nu.
 | 
					As I write, I am running version 0.91 of nu.
 | 
				
			||||||
Similar to fish, it not being a POSIX shell means that you still need to drop
 | 
					Similar to fish,
 | 
				
			||||||
into bash or zsh in order to source env files in order to,
 | 
					it not being a POSIX shell means that you still need to drop into bash or zsh in order to source env files in order to,
 | 
				
			||||||
for example, use a cross-compiling c/c++ sdk.
 | 
					for example, use a cross-compiling c/c++ sdk.
 | 
				
			||||||
(thankfully, python virtualenvs already come with a nu script for you to source,
 | 
					(thankfully, python virtualenvs already come with a nu script for you to source,
 | 
				
			||||||
so doing python dev will not require you to launch a POSIX shell)
 | 
					so doing python dev will not require you to launch a POSIX shell)
 | 
				
			||||||
| 
						 | 
					@ -362,14 +356,12 @@ def recently-modified [
 | 
				
			||||||
> recently-modified --cutoff '2 weeks ago' ./
 | 
					> recently-modified --cutoff '2 weeks ago' ./
 | 
				
			||||||
{{</highlight>}}
 | 
					{{</highlight>}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Its certainly not the most ergonomic, but seems to be the best way at the moment
 | 
					Its certainly not the most ergonomic,
 | 
				
			||||||
to make 'scripts' that are integrated with the rest of nushell.
 | 
					but seems to be the best way at the moment to make 'scripts' that are integrated with the rest of nushell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## So, overall, is it worth it?
 | 
					## So, overall, is it worth it?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Nushell is certainly an promising project, and I will almost certainly be
 | 
					Nushell is certainly an promising project, and I will almost certainly be continuing to use it as my daily shell.
 | 
				
			||||||
continuing to use it as my daily shell. It cant do everything, but dropping into
 | 
					It cant do everything, but dropping into zsh for a task or two every once in a while isnt that big a deal for me,
 | 
				
			||||||
zsh for a task or two every once in a while isnt that big a deal for me, and
 | 
					and having access to such a powerful shell by default has made other tasks much easier.
 | 
				
			||||||
having access to such a powerful shell by default has made other tasks much
 | 
					If you regularly use pipelines in your default shell, consider giving Nushell a try.
 | 
				
			||||||
easier for me. If you regularly use pipelines in your default shell, consider
 | 
					 | 
				
			||||||
giving Nushell a try.
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue