hack.less wip
parent
48af6fa551
commit
efa3c2968f
12
config.yaml
12
config.yaml
|
@ -13,6 +13,18 @@ markup:
|
|||
goldmark:
|
||||
renderer:
|
||||
unsafe: true
|
||||
highlight:
|
||||
anchorLineNos: false
|
||||
codeFences: true
|
||||
guessSyntax: false
|
||||
hl_Lines: ""
|
||||
lineAnchors: ""
|
||||
lineNoStart: 1
|
||||
lineNos: false
|
||||
lineNumbersInTable: true
|
||||
noClasses: true
|
||||
style: solarized-light
|
||||
tabWidth: 2
|
||||
|
||||
menu:
|
||||
main:
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
---
|
||||
title: Test article
|
||||
date: 2021-08-20
|
||||
tags:
|
||||
- NixOS
|
||||
summary: >
|
||||
shows all types of things
|
||||
---
|
||||
|
||||
In this article we are discussing a concrete setup with concrete tools and a concrete language.
|
||||
But the solutions described here, are intended to help you with your set up.
|
||||
|
||||
## Listings
|
||||
|
||||
Here are the Tools used.
|
||||
|
||||
* [Spacemacs](http://spacemacs.org/) : my editor or choice.
|
||||
* [all-hies](https://github.com/Infinisil/all-hies) : to start a [haskell-ide-engine](https://github.com/haskell/haskell-ide-engine) which is the haskell-lsp-server.
|
||||
* [direnv](https://direnv.net/) : to automatically load `shell.nix` configuration in my editor, when opening a file.
|
||||
* [lsp-haskell.el](https://github.com/emacs-lsp/lsp-haskell) : the emacs plugin to interact with the haskell-ide-engine.
|
||||
* [nix-shell](https://nixos.wiki/wiki/Development_environment_with_nix-shell) : because all projects should have one.
|
||||
|
||||
## Big parts
|
||||
|
||||
{{% content-big %}}
|
||||
```shell
|
||||
#!/usr/bin/env bash
|
||||
This is a very big part, when I need more space than usual.
|
||||
```
|
||||
{{% /content-big %}}
|
||||
|
||||
### Goal
|
||||
|
||||
* Configure Spacemacs as much as possible via `configuration.nix`, without the `lsp-server` being configured by the `configuration.nix`.
|
||||
* The `lsp-server` setup should be fully defined inside the `shell.nix` of the project I'm working on.
|
||||
|
||||
This way project specific tweaks are stored in the place where it belongs,
|
||||
and other people can use their favorite IDE with the same setup.
|
||||
|
||||
## Configure Spacemacs
|
||||
|
||||
Spacemacs is basically an `~/.emacs.d` folder and a mutable file `~/.spacemacs`.
|
||||
I tried to configure `~/.spacemacs` via [home-manager](https://github.com/rycee/home-manager)
|
||||
but this does not play well with updates and with `customization`.
|
||||
|
||||
Now I'm using [home-manager](https://github.com/rycee/home-manager)
|
||||
to configure files in `~/.spacemacs.d/` and `load` them in
|
||||
the configuration functions inside `~/.spacemacs`. A simple `(load "~/.spacemacs.d/hook-user-config.el")`
|
||||
inside the `dotspacemacs/user-config` function is enough, to make it work.
|
||||
|
||||
```nix
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
|
||||
user = "mainUser";
|
||||
userName = config.users.users."${user}".name;
|
||||
home = config.users.users."${user}".home;
|
||||
fontSize = 14;
|
||||
|
||||
startupBanner = pkgs.fetchurl{
|
||||
url = "https://github.com/NixOS/nixos-homepage/raw/master/logo/nix-wiki.png";
|
||||
sha256 = "1hrz7wr7i0b2bips60ygacbkmdzv466lsbxi22hycg42kv4m0173";
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
systemd.services =
|
||||
let
|
||||
clone =
|
||||
repository: folder: branch:
|
||||
{
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "clone ${repository} to ${folder}";
|
||||
serviceConfig.User = userName;
|
||||
unitConfig.ConditionPathExists = "!${folder}";
|
||||
script = ''
|
||||
${pkgs.git}/bin/git clone ${repository} --branch ${branch} ${folder}
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
emacs-pull = clone "https://github.com/syl20bnr/spacemacs" "${home}/.emacs.d" "master";
|
||||
};
|
||||
|
||||
home-manager.users."${user}" = {
|
||||
|
||||
home.file.".spacemacs.d/hook-init.el".text = ''
|
||||
;; just add (load "~/.spacemacs.d/hook-init.el")
|
||||
;; at the end of dotspacemacs/init function
|
||||
|
||||
;; overrides of dotspacemacs/init ()
|
||||
(setq-default
|
||||
dotspacemacs-themes '(solarized-light solarized-dark)
|
||||
dotspacemacs-startup-banner "${startupBanner}"
|
||||
dotspacemacs-default-font '("Terminus"
|
||||
:size ${toString fontSize}
|
||||
:weight normal
|
||||
:width normal
|
||||
:powerline-scale 1.1))
|
||||
'';
|
||||
|
||||
home.file.".spacemacs.d/hook-layers.el".text = ''
|
||||
;; just add (load "~/.spacemacs.d/hook-layers.el")
|
||||
;; at the end of dotspacemacs/layers function
|
||||
|
||||
(let
|
||||
((user-layers dotspacemacs-configuration-layers))
|
||||
(setq
|
||||
dotspacemacs-configuration-layers
|
||||
(append user-layers
|
||||
'( spell-checking
|
||||
syntax-checking
|
||||
(haskell :variables
|
||||
haskell-enable-hindent t
|
||||
haskell-completion-backend 'lsp
|
||||
haskell-enable-hindent-style "gibiansky"
|
||||
haskell-process-type 'cabal-new-repl)
|
||||
))))
|
||||
|
||||
(let
|
||||
((user-packages dotspacemacs-additional-packages ))
|
||||
(setq
|
||||
dotspacemacs-additional-packages
|
||||
(append user-packages
|
||||
'( lsp-mode
|
||||
lsp-ui
|
||||
lsp-haskell
|
||||
direnv
|
||||
))))
|
||||
'';
|
||||
|
||||
home.file.".spacemacs.d/hook-user-config.el".text = ''
|
||||
;; just add (load "~/.spacemacs.d/hook-user-config.el")
|
||||
;; at the end of dotspacemacs/user-config function
|
||||
|
||||
;; lsp setup for haskell
|
||||
;; hie-wrapper must be installed and configured in the direnv setup
|
||||
(setq lsp-haskell-process-path-hie "hie-wrapper")
|
||||
(setq lsp-response-timeout 60)
|
||||
(require 'lsp-haskell)
|
||||
(add-hook 'haskell-mode-hook #'lsp)
|
||||
(add-hook 'haskell-mode-hook #'direnv-update-environment)
|
||||
'';
|
||||
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
We setup emacs to run `direnve-update-environment` and `lsp` once we start the `haskell-mode`.
|
||||
But we did not install `lsp`.
|
||||
In my setups the `lsp-server` is installed by the project file (lsp.nix), and is loaded via `direnv` (`direnv-update-environment` in emacs).
|
||||
If you don't like that just use the snippet from the next section.
|
||||
|
||||
### Alternative Configuration (install lsp in the configuration.nix)
|
||||
|
||||
You can install the `lsp` (in our case `hie-wrapper`) globally in your `configuration.nix` .
|
||||
I usually do this in my projects (via `lsp.nix`). Here is the part that differs.
|
||||
|
||||
```
|
||||
home.file.".spacemacs.d/hook-user-config.el".text =
|
||||
let
|
||||
all-hies = import (fetchTarball "https://github.com/infinisil/all-hies/tarball/master") {};
|
||||
in ''
|
||||
;; just add (load "~/.spacemacs.d/hook-user-config.el")
|
||||
;; at the end of dotspacemacs/user-config function
|
||||
|
||||
;; lsp setup for haskell
|
||||
(setq lsp-haskell-process-path-hie
|
||||
"${all-hies.selection{ selector = p: { inherit (p) ghc864;}; } }/bin/hie-wrapper")
|
||||
(setq lsp-response-timeout 60)
|
||||
(require 'lsp-haskell)
|
||||
(add-hook 'haskell-mode-hook #'lsp)
|
||||
(add-hook 'haskell-mode-hook #'direnv-update-environment) ;; still needed
|
||||
'';
|
||||
```
|
||||
|
||||
## Setup the project
|
||||
|
||||
For a Haskell project I have this minimal setup of files.
|
||||
|
||||
### lsp.nix
|
||||
|
||||
This file is to setup the `lsp-server`.
|
||||
If you already installed the `lsp-server` via the `configuration.nix`, this file is not necessary,
|
||||
but also does not hurt.
|
||||
|
||||
```
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
let
|
||||
all-hies = import (fetchTarball "https://github.com/infinisil/all-hies/tarball/master") {};
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
haskellPackages.hoogle
|
||||
haskellPackages.hindent
|
||||
haskellPackages.hlint
|
||||
haskellPackages.stylish-haskell
|
||||
(all-hies.selection { selector = p: {inherit (p) ghc864; }; })
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### env.nix
|
||||
|
||||
Provides the environment to run
|
||||
`cabal test` and `cabal build`.
|
||||
All package files (e.g. `./current-project.nix`) are created by `cabal2nix`.
|
||||
|
||||
```
|
||||
{ pkgs ? import <nixpkgs> {
|
||||
overlays = [
|
||||
(self: super: {
|
||||
haskellPackages = super.haskellPackages.override {
|
||||
overrides = self: super: {
|
||||
datetime = super.callPackage ./datetime.nix {};
|
||||
current-project = super.callPackage ./current-project.nix { };
|
||||
};
|
||||
};
|
||||
})];
|
||||
}}:
|
||||
pkgs.haskellPackages.current-project.env
|
||||
```
|
||||
|
||||
### `shell.nix`
|
||||
|
||||
For other scripts and tooling important for development.
|
||||
|
||||
```
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
let
|
||||
updateCabal = pkgs.writeShellScriptBin "update-cabal" /* sh */ ''
|
||||
echo "# created by cabal2nix " > ${toString ./.}/current-project.nix
|
||||
${pkgs.cabal2nix}/bin/cabal2nix ${toString ./.} >> ${toString ./.}/current-project.nix
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
updateCabal
|
||||
openapi-generator-cli
|
||||
openssl
|
||||
cabal2nix
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### `.envrc`
|
||||
|
||||
finally we need a `direnv` configuration file.
|
||||
`direnv` and the `direnv-mode` make it possible
|
||||
to load the environment needed and provided by the `*.nix` files.
|
||||
|
||||
```
|
||||
use nix ./env.nix
|
||||
use nix ./lsp.nix
|
||||
use nix ./shell.nix
|
||||
```
|
||||
Don't forget to run `direnv allowed . ` in the project folder.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Now we are capable to use the `lsp-server` configured in all our projects,
|
||||
with the editor we prefer.
|
||||
Your colleagues will have little problems with the setup and improve it.
|
||||
|
||||
If you prefer to install the lsp globally, you can simply do that as described,
|
||||
this will not interfere with the `lsp` server setup in the `lsp.nix` file.
|
||||
|
||||
I'm running this setup for quite a while now, and
|
||||
I experience little to no problems with it.
|
||||
The most common thing is that I have to fire `lsp-restart-workspace` to remove old errors,
|
||||
but doing this every hour is not a problem for me.
|
||||
|
||||
### Support
|
||||
|
||||
If you have comments or problems just ping me `palo @ irc.freenode.net`
|
|
@ -0,0 +1,5 @@
|
|||
</div>
|
||||
<div class="content-big">
|
||||
{{ .Inner }}
|
||||
</div>
|
||||
<div class="content">
|
|
@ -1,25 +1,27 @@
|
|||
@import "color-gruvbox.less";
|
||||
|
||||
@color-code-background: rgb(224, 224, 206);
|
||||
@color-code-border: rgb(223, 210, 142);
|
||||
@color-code-inline: rgb(22, 34, 0);
|
||||
@color-body-background: @gb-lm-bg0-hard;
|
||||
@color-body-font: @gb-lm-fg0;
|
||||
|
||||
@color-code-border: @gb-lm-dark-yellow;
|
||||
@color-code-inline: @gb-lm-dark-yellow;
|
||||
|
||||
@color-note-background: rgb(182, 201, 182);
|
||||
@color-note-border: rgb(172, 216, 132);
|
||||
|
||||
@color-warning-background: rgba(188, 32, 11, 0.55);
|
||||
|
||||
@color-comparison-good: #ABE953;
|
||||
@color-comparison-ok: #E9E653;
|
||||
@color-comparison-bad: #E96D53;
|
||||
@color-comparison-good: @gb-dm-light-green;
|
||||
@color-comparison-ok: @gb-dm-light-yellow;
|
||||
@color-comparison-bad: @gb-dm-light-red;
|
||||
|
||||
@color-nav-background: rgb(241, 241, 192);
|
||||
@color-nav-underline: rgb(156, 110, 110);
|
||||
@color-nav-text: rgb(64, 78, 111);
|
||||
@color-nav-item-border: rgb(59, 206, 59);
|
||||
@color-nav-item-border-active: rgb(213, 230, 62);
|
||||
@color-nav-background: @gb-lm-bg0;
|
||||
@color-nav-underline: @gb-lm-fg1;
|
||||
@color-nav-text: @color-body-font;
|
||||
|
||||
@color-sidebar-font: rgb(0, 0, 0);
|
||||
|
||||
// todo
|
||||
@color-pages-list: rgb(159, 197, 159);
|
||||
@color-pages-list-border: rgb(15, 49, 15);
|
||||
@color-pages-list-text: rgb(0, 0, 0);
|
|
@ -1,7 +1,9 @@
|
|||
@font-normal: ~"'Roboto', sans-serif";
|
||||
|
||||
@font-code: ~"'Inconsolata', monospace";
|
||||
@font-header: ~"'Zilla Slab', serif";
|
||||
//@font-header: ~"'Inconsolata', monospace";
|
||||
|
||||
@font-header: ~"'Roboto', sans-serif";
|
||||
//@font-header: ~"'Zilla Slab', serif";
|
||||
|
||||
@font-height: 1.7em;
|
||||
@font-code-height: 1.1em;
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
//@import "color.less";
|
||||
//@import "media-types.less";
|
||||
//@import "font.less";
|
||||
|
||||
// code blocks
|
||||
//pre {
|
||||
// padding: 2rem;
|
||||
// margin: 1.75rem 0;
|
||||
// background-color: #fff;
|
||||
// border: 1px solid #ccc;
|
||||
// overflow: auto
|
||||
//}
|
||||
//
|
||||
//code[class*=language-], pre[class*=language-], pre code {
|
||||
// font-weight: 100;
|
||||
// text-shadow: none;
|
||||
// margin: 1.75rem 0
|
||||
//}
|
||||
|
||||
|
||||
pre {
|
||||
//background: @color-code-background;
|
||||
|
||||
margin-left: 0em;
|
||||
margin-right: 0em;
|
||||
|
||||
padding-left: @special-info-padding-side ;
|
||||
padding-top: .7em ;
|
||||
padding-right: .0em;
|
||||
padding-bottom: 0.7em;
|
||||
|
||||
border-left: .4em solid @color-code-border;
|
||||
border-right: 1px solid @color-code-border;
|
||||
border-top: 1px solid @color-code-border;
|
||||
border-bottom: 1px solid @color-code-border;
|
||||
white-space: pre-wrap;
|
||||
|
||||
font-weight: normal;
|
||||
font-family: @font-code;
|
||||
line-height: @font-code-height;
|
||||
|
||||
code {
|
||||
font-weight: normal;
|
||||
font-family: @font-code;
|
||||
line-height: @font-code-height;
|
||||
}
|
||||
}
|
||||
|
||||
// inline code
|
||||
.inline-code{
|
||||
color: @color-code-inline;
|
||||
|
||||
//font-weight: bold;
|
||||
font-family: @font-code;
|
||||
}
|
||||
|
||||
p > code {
|
||||
.inline-code();
|
||||
}
|
||||
|
||||
li > code {
|
||||
.inline-code();
|
||||
}
|
|
@ -1,22 +1,22 @@
|
|||
@import "color.less";
|
||||
@import "font.less";
|
||||
//@import "color.less";
|
||||
//@import "font.less";
|
||||
|
||||
@import "main-hack-code.less";
|
||||
|
||||
// Header
|
||||
header {
|
||||
h1 {
|
||||
position: relative;
|
||||
display: table-cell;
|
||||
padding: 20px 0 30px;
|
||||
margin: 0;
|
||||
overflow: hidden
|
||||
}
|
||||
h1 {
|
||||
position: relative;
|
||||
display: table-cell;
|
||||
padding: 20px 0 30px;
|
||||
margin: 0;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
h1:after {
|
||||
content: "====================================================================================================";
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0
|
||||
}
|
||||
h1:after {
|
||||
content: "====================================================================================================";
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0
|
||||
}
|
||||
|
||||
h2:before, h3:before, h4:before, h5:before, h6:before {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
@import "color.less";
|
||||
@import "font.less";
|
||||
//@import "color.less";
|
||||
//@import "font.less";
|
||||
|
||||
body {
|
||||
#main-navigation {
|
||||
//background-color: @color-nav-background;
|
||||
background-color: @color-nav-background;
|
||||
|
||||
//position: fixed;
|
||||
|
||||
width: 100%;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
@import "color.less";
|
||||
@import "media-types.less";
|
||||
@import "font.less";
|
||||
|
||||
@import "main-navigation.less";
|
||||
@import "main-hack.less";
|
||||
@import "main-toc.less";
|
||||
|
@ -12,6 +13,9 @@
|
|||
@special-info-padding-side: 0.5em;
|
||||
|
||||
body {
|
||||
background-color: @color-body-background;
|
||||
font-family: @font-normal;
|
||||
color: @color-body-font;
|
||||
margin: 0px;
|
||||
|
||||
header{
|
||||
|
@ -20,72 +24,20 @@ body {
|
|||
margin-right: auto;
|
||||
}
|
||||
.content {
|
||||
h2,h3,h4,h5,h6,p,pre,div,ul,table,figure,ol{
|
||||
width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
.content-big {
|
||||
width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
h1,h2,h3,h4 {
|
||||
font-family: @font-header;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
// ???
|
||||
.block-margin {
|
||||
margin-top: .65em;
|
||||
margin-bottom: .65em;
|
||||
}
|
||||
|
||||
|
||||
pre {
|
||||
background: @color-code-background;
|
||||
|
||||
.block-margin();
|
||||
margin-left: 0em;
|
||||
margin-right: 0em;
|
||||
|
||||
padding-left: @special-info-padding-side ;
|
||||
padding-top: .7em ;
|
||||
padding-right: .0em;
|
||||
padding-bottom: 0.7em;
|
||||
|
||||
border-left: .4em solid @color-code-border;
|
||||
white-space: pre-wrap;
|
||||
|
||||
font-weight: normal;
|
||||
font-family: @font-code;
|
||||
line-height: @font-code-height;
|
||||
|
||||
code {
|
||||
font-weight: normal;
|
||||
font-family: @font-code;
|
||||
line-height: @font-code-height;
|
||||
}
|
||||
code.nix {
|
||||
background: @color-code-background;
|
||||
}
|
||||
}
|
||||
|
||||
.inline-code{
|
||||
color: @color-code-inline;
|
||||
|
||||
font-weight: bold;
|
||||
font-family: @font-code;
|
||||
}
|
||||
|
||||
p > code {
|
||||
.inline-code();
|
||||
}
|
||||
|
||||
li > code {
|
||||
.inline-code();
|
||||
}
|
||||
|
||||
p {
|
||||
.block-margin();
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.note {
|
||||
|
@ -96,10 +48,8 @@ p {
|
|||
padding-top: .4em;
|
||||
padding-bottom: .4em;
|
||||
|
||||
.block-margin();
|
||||
|
||||
p {
|
||||
.block-margin();
|
||||
margin-left: @special-info-padding-side;
|
||||
|
||||
padding-top: .0em;
|
||||
|
@ -108,10 +58,6 @@ p {
|
|||
|
||||
pre {
|
||||
|
||||
background: @color-code-background;
|
||||
|
||||
.block-margin();
|
||||
|
||||
margin-left: 0;
|
||||
padding-left: @special-info-padding-side * 2 ;
|
||||
padding-right: @special-info-padding-side * 2 ;
|
||||
|
@ -130,7 +76,6 @@ p {
|
|||
table.comparison {
|
||||
width: 100%;
|
||||
|
||||
.block-margin();
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
|
||||
|
|
Loading…
Reference in New Issue