Nginx-Perl[docker][alpine]

# dockerでalpineを使ってNginxとPerlと

試行錯誤して動くようになったので、記録と部品である。

## ディレクトリツリー

### ~/docker/@alpine/Nginx-Perl/

```sh
cd ~/docker/@alpine/Nginx-Perl
tree
```
<details><summary>ツリーリスト</summary>
* 使っていない
  * _ARCディレクトリ
    * 圧縮ファイル
    * Notoフォント
  * _junkディレクトリ
  * testディレクトリ

```markdown
.
├── Dockerfile
├── _ARC
│   ├── IPAexfont00301.zip
│   ├── IPAexfont00401.zip
│   ├── IPAfont00303.zip
│   ├── NotoSansCJKjp-hinted.zip
│   ├── NotoSerifCJKjp-hinted.zip
│   └── font
│       ├── NotoSansCJKjp-Black.otf
│       ├── NotoSansCJKjp-Bold.otf
│       ├── NotoSansCJKjp-DemiLight.otf
│       ├── NotoSansCJKjp-Light.otf
│       ├── NotoSansCJKjp-Medium.otf
│       ├── NotoSansCJKjp-Regular.otf
│       ├── NotoSansCJKjp-Thin.otf
│       ├── NotoSansMonoCJKjp-Bold.otf
│       ├── NotoSansMonoCJKjp-Regular.otf
│       ├── NotoSerifCJKjp-Black.otf
│       ├── NotoSerifCJKjp-Bold.otf
│       ├── NotoSerifCJKjp-ExtraLight.otf
│       ├── NotoSerifCJKjp-Light.otf
│       ├── NotoSerifCJKjp-Medium.otf
│       ├── NotoSerifCJKjp-Regular.otf
│       ├── NotoSerifCJKjp-SemiBold.otf
│       ├── ipaexg.ttf
│       └── ipaexm.ttf
├── _junk
│   ├── default.conf
│   ├── docker-entrypoint.sh
│   ├── fcgiwrap.sh
│   ├── fpm-pool.conf
│   ├── ikiwiki-setup.sh
│   ├── nginx-ikiwiki.conf
│   ├── nginx.conf
│   ├── php.ini
│   ├── ppp.sh
│   └── supervisord.ini
├── alpine
│   ├── bin
│   │   ├── fd
│   │   ├── fd-dict.txt
│   │   ├── kanjicnv
│   │   ├── lv
│   │   ├── mkcat
│   │   ├── mkdict
│   │   ├── mkkanji
│   │   ├── mkmfsed
│   │   ├── mktankan
│   │   ├── mkunitbl
│   │   └── ng
│   └── locale
│       ├── Tokyo
│       ├── ja_JP.UTF-8
│       ├── locale
│       └── musl-locales.mo
├── config
│   ├── http.d
│   │   └── default.conf
│   └── nginx.conf
├── root
│   ├── gg.sh
│   └── init.el
├── test
│   ├── default.conf
│   └── nginx.conf
└── www-home
    ├── index.cgi
    ├── index.html
    ├── index.php
    ├── styles.css
    └── test.html

12 directories, 60 files
[debian Nginx-Perl]$ 
```

</details>

## Dockerfileファイル

コメントアウトして残してあるのは作業用。たぶん、振り返りもしないし、スグに忘れる。むしろぶん投げて忘れるためにコメントで残している。

振り返り箇条書き

1. 作業環境（ストレス軽減）
   1. wikiエンジンを組み込む検証作業用で環境を作っていた
   1. emacs - viに疲れ脳死で emacs 入れたら外せなくなった
   1. bash - /bin/sh つらい
   1. fdclone - コマンドつらい
   1. ローカライズ - 日本語環境、漢字環境
      * ローカライズは別イメージで作ってバイナリをコピーしてる
1. システムタスクマネージャー
   1. openRC - 動作不良調査が不毛に思えたのでぶん投げた
   1. supervisord - 飽きた
   1. /root/entrypoint-hook.sh - docker compose からの介入に使っているサイトを見てパクってそのまま残している。何に使うのか不明のままなので、気分で消すと思う
   1. /root/gg.sh - テストで使っている。むしろ便利過ぎて、他にいらない気分のまま使っている
1. nginx - ずっと使ってみたかったのだ（時間に余裕できた）
1. perl - perl製wikiエンジンの検証環境なの
   1. fcgiwrap - ファーストcgiラッパー
   1. spawn-fcgi - すぱーん

```Dockerfile
# cp -adfPru /var/docker/* ./
# cd ~/docker/@alpine/ikiwiki/
# docker build -t ikiwiki .
# docker run --name iki-d -it -u root -p 8080:80 -v "$PWD:/work" ikiwiki bash
# codker ps -a
# docker exec -it iki-d bash
#
# [docker] # gg.sh
FROM alpine:latest
RUN apk add --no-cache ncurses shadow \
        bash emacs-nox curl wget \
        the_silver_searcher the_silver_searcher-bash-completion

RUN mkdir -p /usr/share/locale/ja_JP/LC_MESSAGES \
 && mkdir -p /usr/share/zoneinfo/Asia \
 && mkdir -p /usr/share/i18n/locales/musl \
 && mkdir -p /root/.emacs.d

WORKDIR /worker

COPY ./root/* /root/
COPY ./root/init.el /root/.emacs.d/
COPY ./alpine/bin/* /usr/local/bin/
COPY ./alpine/locale/locale /usr/bin/
COPY ./alpine/locale/Tokyo /etc/localtime
COPY ./alpine/locale/Tokyo /usr/share/zoneinfo/Asia/
COPY ./alpine/locale/musl-locales.mo /usr/share/locale/ja_JP/LC_MESSAGES/
COPY ./alpine/locale/ja_JP.UTF-8 /usr/share/i18n/locales/musl/
RUN echo Asia/Tokyo > /etc/timezone \
 && echo js_JP.utf8 UTF-8 >> /etc/locale.gen
ENV LOCALE="js_JP.utf8 UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LANG="C.UTF-8" \
    LC_ALL="ja_JP.UTF-8" \
    TZ="Asia/Tokyo"

## 日本語フォント
RUN apk add --no-cache fontconfig fontconfig
RUN mkdir -p /usr/share/fonts
COPY ./_ARC/font/ipaex* /usr/share/fonts/
RUN mkdir -p ~/.config/fontconfig

RUN << 'EOF' cat > ~/.config/fontconfig/fonts.conf
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<!-- Default serif fonts -->
 <match target="pattern">
   <test qual="any" name="family"><string>serif</string></test>
   <edit name="family" mode="prepend" binding="same"><string>IPAPMincho</string></edit>
 </match>
</fontconfig>
EOF

RUN fc-cache -f

## ------------------------------------------------------------
## Maintenance Tools configration
## コメントアウト docker COPY コマンドで直接コピーする事にした

# RUN << 'EOF' cat >> /root/.fd2rc
# PAGER=lv
# EDITOR=emacs
# SHELL=/bin/bash
# SORTTYPE=201
# DISPLAYMODE=3
# ANSICOLOR=1
# EOF

# RUN << 'EOF' cat >> ~/.bashrc
# echo "source load ${PWD}/.bashrc"
# alias ls='ls --color=auto'
# alias ll='ls -alF'
# alias la='ls -A'
# alias l='ls -CF'
# alias grep='grep --color=auto'
# alias fgrep='fgrep --color=auto'
# alias egrep='egrep --color=auto'
# EOF

# RUN << 'EOF' cat >> ~/.profile
# echo "source load ${PWD}/.profile"
# EOF
## ------------------------------------------------------------
# Packages _____________________________________________________________________
#RUN apk add openrc nginx-openrc \

RUN apk add make

RUN apk add nginx nginx-mod-http-fancyindex \
    nginx-mod-http-perl \
    fcgiwrap spawn-fcgi \
    perl-app-cpanminus \
    cgif \
    perl-doc \
    perl-cgi perl-fcgi perl-cgi-session

COPY ./config/nginx.conf /etc/nginx/nginx.conf
COPY ./config/http.d/default.conf /etc/nginx/http.d/default.conf
RUN cpanm URI Test Clone HTTP::Headers HTML::Entities

RUN mkdir -p /wiki/html
COPY ./www-home/* /wiki/html
RUN chown -R nobody:nobody /wiki/html \
 && chmod +x /wiki/html/index.cgi

EXPOSE 80
WORKDIR /work
WORKDIR /worker

# RUN apk add --update --no-cache socat
# # health check: test fcgiwrap socket listener
# HEALTHCHECK --interval=30s --timeout=3s \
#   CMD socat -u OPEN:/dev/null UNIX-CONNECT:/var/run/fcgiwrap.socket || exit 1

# entrypoint and services
ENV PATH=/root:${PATH}
RUN << 'EOF' cat > /root/gg.sh
#!/bin/sh
cd /root
# entrypoint-hook.sh 変更する事で docker イメージに接続しないまま動作を更新できる（かも）
test -f /root/entrypoint-hook.sh && sh /root/entrypoint-hook.sh

# fcgiwrap だけの場合
# pkill -f "fcgiwrap -s unix:/var/run/fcgiwrap/fcgiwrap-nginx.sock"
# rm -f /var/run/fcgiwrap/fcgiwrap-nginx.sock
# nohup /usr/bin/spawn-fcgi -u nobody -g nobody -s unix:/var/run/fcgiwrap/fcgiwrap-nginx.sock -n -- /usr/bin/fcgiwrap &
# while ! [ -S /var/run/fcgiwrap/fcgiwrap-nginx.sock ]; do sleep .2; done
# chown nobody:nobody /var/run/fcgiwrap/fcgiwrap-nginx.sock
# test -f nohup.out && rm ./nohup.out

# spawn-fcgi を併用する場合
nohup /usr/bin/spawn-fcgi -u nobody -g nobody -s /var/run/fcgiwrap/fcgiwrap-nginx.sock -n -- /usr/bin/fcgiwrap &
while ! [ -S /var/run/fcgiwrap/fcgiwrap-nginx.sock ]; do sleep .2; done
test -f ./nohup.out && rm ./nohup.out

# nginx
/usr/sbin/nginx -g "daemon off;" -c /etc/nginx/nginx.conf
EOF
RUN chmod +x /root/gg.sh
# ADD entrypoint.sh .
# ENTRYPOINT ["sh", "./entrypoint.sh"]
# ENTRYPOINT ["sh", "/root/gg.sh"]
```

### fcgiwrapとspawn-fcgi

#### fcgiwrap

nginxがperlを呼び出す時に、ソケット・TCP経由で起動から返却プロセスを丸投げする仕組み。
個人的な推測だけど、同一サーバ内でwww-perlを遣り取りしてる場合、メリットなんぞ無いんじゃないかなと思う。mod-perl使え。

使ってみたいから使うのは、ちょっと駄目な人が透けて見える。
将来の拡張性のため、バッチサーバを別に建て負荷分散する時のため、いま現在、勉強として学習のために使うとか、適当な理由があれば良いと思う。

#### spawn-fcgi

fcgiwrap プロセスが30個くらい並んでいたのを見て、プロセス起動終了管理しないと駄目かなと調べてた時に見つけた。と言うか、コレ使えと書いてあった。
fcgiwrap 単独で使う時に不便に思うことが、こいつを使うことで解消された。

## config/nginx.conf

長くて理解出来なかったので短くした。
商業リリースする時とかはちゃんとしてほしい。
２行目〜４行目に書いてあるコメントは ```/root/gg.sh``` にある、nginx起動コマンドについてである。
主体が何かを省略する習性が、日本人には含有率高めっぽいが、直したい。

```conf
# /etc/nginx/nginx.conf
# コマンド引数で "daemon off;" 指定しているので conf に記述すると重複定義エラーになる
# /usr/sbin/nginx -g "daemon off;" -c /etc/nginx/nginx.conf
# daemon off;
user    nobody nobody;
worker_processes 1;
error_log stderr notice;
include /etc/nginx/modules/*.conf;
include /etc/nginx/conf.d/*.conf;
events {
  worker_connections 32;
}
http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  access_log /dev/stdout;
  server_tokens off;
  client_max_body_size 1m;
  sendfile on;
  tcp_nopush on;
  ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:2m;
  ssl_session_timeout 1h;
  ssl_session_tickets off;
  gzip_vary on;
  map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
  }
  log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  		'$status $body_bytes_sent "$http_referer" '
  		'"$http_user_agent" "$http_x_forwarded_for"';
  include /etc/nginx/http.d/*.conf;
}
```

## config/http.d/default.conf

```conf
server {
  listen      80 default_server;
  listen [::]:80 default_server;
  #server_name localhost:8080;
  root /wiki/html;
  index  index.html index.htm index.php index.cgi;
  location / {
    # # root html;
    # index index.html index.htm index.php index.cgi index.pl;
    # autoindex on;
    fancyindex on;              # Enable fancy indexes.
    fancyindex_exact_size off;  # Output human-readable file sizes.
    fancyindex_localtime on;
    fancyindex_footer "footer.html";
    fancyindex_ignore "footer.html";
  }
  location ~ \.(pl|cgi)$ {
    gzip off;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    include         fastcgi_params;
    fastcgi_pass    unix:/run/fcgiwrap/fcgiwrap-nginx.sock;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  }
  #location ~ \.php$ {
  # fastcgi_pass    unix:/run/fcgiwrap/fcgiwrap-nginx-php.sock;
  # fastcgi_param   SCRIPT_FILENAME  /scripts$fastcgi_script_name;
  # include         fastcgi_params;
  #}
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   html;
  }
  location = /404.html {
    internal;
  }
  location ~ /\.ht {
    deny  all;
  }
}
```

## 蛇足

### www-home/index.cgi

<details><summary>/www/html/index.cgi</summary>

```perl
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
# https://perldoc.jp/docs/modules/CGI-3.49/CGI.pod
# https://netlog.jpn.org/r271-635/2011/03/perl_cgi_pm_html_start.html
# https://perldoc.perl.org/5.20.0/CGI
#use CGI qw/-no_xhtml -debug/;
#use CGI qw(-debug);
use CGI qw/-no_xhtml/;
use CGI::Carp 'fatalsToBrowser';

my $q = CGI->new;
my %headers = map { $_ => $q->http($_) } $q->http();

# Print HTTP header and start HTML
print $q->header(-type=>'text/html', -charset=>'utf-8');
# https://netlog.jpn.org/r271-635/2011/03/perl_cgi_pm_html_start.html
print $q->start_html(
    -title=>"[テスト] **Environment Variables**",
    -lang=>'ja-JP',
    #-script=>{-type=>'text/javascript',-src=>'script.js'},
    -style=>[
	 {'src'=>'styles.css'}
	 # {'src'=>'styles2.css'},
	 # {'code'=>'h1{color:red;font-size:10pt;}'}
    ],
    -xbase=>$q->url(-absolute=>1),
    -target=>'_new',
    -meta=>{
	'robots'=>'nofollow,noarchive',
	    'description'=>'CGIのテスト',
	    'keywords'=>'キーワード1,キーワード2',
	    'copyright'=>'copyright 2011 abcd efgh',
	    'author'=>'abcd efgh',
	    'generator'=>'perl 5',
    },
    -meta  => { 'viewport' => 'width=device-width, initial-scale=1.0' },
    -meta  => {-http_equiv=>'refresh', -content=>'100; URL=index.cgi'}
    );

print "<h1>This is Perl CGI Test with Nginx</h1>\n";
# Display environment variables
print "<h1>Environment Variables</h1>\n";
print "<table class=\"fantasy-table\">\n";
print "<tr><th>Header</th><th>Value</th></tr>\n";

for my $header ( sort keys %headers ) {
    # print "$header: $headers{$header}\n";
    print "<tr><td><code>${header}</code></td><td><code>$headers{$header}</code></td></tr>\n";
}

print "<tr><th>Variable</th><th>Value</th></tr>\n";

# Iterate through %ENV and display key-value pairs
foreach my $key (sort keys %ENV) {
    print "<tr><td><code>${key}</code></td><td><code>$ENV{$key}</code></td></tr>\n";
}

print "</table>\n";
print $q->end_html;
print "\n";
exit;
```

</details>

### www-home/index.html

<details><summary>/www/html/index.html</summary>

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>This static HTML file is served by Nginx - Alpine Linux</title>
</head>
<html>
<head>
<style>
body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;}
</style>
</head>
<body>
<h1>This static HTML file is served by Nginx - Alpine Linux</h1>
<p>
  <h2>Glossary</h2>
  <dl>
    <dt>Nginx</dt>
    <dd>karui hayai umai. test ni saiteki.</dd>
    
    <dt>Job control</dt>
    <dd>suer nantoka is darui x. openrc is ugokanai x. sh script is ok rakuchin.</dd>
    
    <dt>fcgiwrap</dt>
    <dd>kick cgi and bypass execute.</dd>

    <dt>spawn-fcgi</dt>
    <dd>kill process is fcgiwrap. permission change socket.</dd>
  </dl>
</p>
<p><em>Thank you.</em></p>
</body>
</html>
```

</details>

### www-home/index.php

```php
<?php
phpinfo();
```

### www-home/styles.css

<details><summary>/www/html/styles.css</summary>

```css
/* styles.css */
body {
  font-family: 'Cinzel', serif;
  background: linear-gradient(135deg, #1e1e2f, #3a3a5f);
  color: #fff;
  #display: flex;
  justify-content: center;
  align-items: center;
}

.fantasy-table {
  border-collapse: collapse;
  width: 80%;
  max-width: 600px;
  margin: 0 auto;
  background: rgba(0, 0, 0, 0.7);
  border: 2px solid #6a0dad;
  box-shadow: 0 0 20px #6a0dad, 0 0 40px #ff00ff;
  border-radius: 10px;
  overflow: hidden;
}

.fantasy-table thead {
  background: linear-gradient(90deg, #6a0dad, #ff00ff);
}

.fantasy-table th, .fantasy-table td {
  padding: 8px;
  #text-align: center;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.fantasy-table th {
  color: #fff;
  font-size: 1.2em;
  text-shadow: 0 0 5px #fff, 0 0 10px #ff00ff;
}

.fantasy-table tbody tr {
  transition: all 0.3s ease;
}

.fantasy-table tbody tr:nth-child(even) {
  background: rgba(255, 255, 255, 0.1);
}

.fantasy-table tbody tr:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.02);
  box-shadow: 0 0 10px #ff00ff, 0 0 20px #6a0dad;
}

.fantasy-table td {
  color: #ddd;
  font-size: 1.3em;
  text-shadow: 0 0 3px #fff;
}

```

</details>


### init.el

メイン機から軽い設定だけを抜いて来た

軽い ＝ パッケージと関係ない部分だけだから軽い

<details><summary>/root/.emacs.d/init.el</summary>

```emacs-lisp
>(require 'ffap)
(ffap-bindings)

(global-unset-key (kbd "C-/"))
(global-unset-key (kbd "C-S-/"))
(global-set-key (kbd "C-/")         'undo)
(global-set-key (kbd "C-S-/")       'undo-redo)
(global-set-key (kbd "C-c C-c")     'kill-buffer)
(global-set-key (kbd "C-c C-r")     'eval-region)
(global-set-key (kbd "C-x C-b")     'ibuffer)
(global-set-key (kbd "C-x C-f")     'find-file-at-point)
;; (global-set-key (kbd "C-x C-f")     'ffap)
;; (global-set-key (kbd "C-x k")       'kill-this-buffer) ;; kill-buffer
(global-set-key (kbd "C-x f")       'find-file)
(global-set-key (kbd "C-x x f")     'find-function)
(global-set-key (kbd "C-x x v")     'find-variable)
;; 
;; (global-set-key (kbd "RET")         'electric-newline-and-maybe-indent)
;; (global-unset-key [down-mouse-3])
;; マウスの右クリックメニューを使えるようにする
(defun my/init/bingalls-edit-menu (event) (interactive "e") (popup-menu menu-bar-edit-menu))
(global-set-key [up-mouse-3] 'my/init/bingalls-edit-menu)

;;(global-set-key (kbd "C-x k")       '(kill-this-buffer (current-buffer))) ;; kill-buffer
(bind-key "k" (lambda () (interactive) (kill-buffer (current-buffer))) ctl-x-map)
(bind-key "#" (lambda () (interactive) (client-save-kill-emacs)) ctl-x-map)

(setq ad-redefinition-action 'accept)

(global-auto-revert-mode t)     ;; 他でファイルの編集が行われた場合、再読み込みする

(setq vc-follow-symlinks t)
;; (setq vc-follow-symlinks nil)

;; (if (fboundp 'display-line-numbers-mode)
;;     (global-display-line-numbers-mode 1)
;;   (global-linum-mode 1))
(global-hl-line-mode +1)        ;; 現在行を強調
(custom-set-faces '(hl-line ((t (:background unspecified :underline t)))))
;; (custom-set-faces '(hl-line ((t (:background "color-236" :underline t)))))
;; (set-face-attribute hl-line-face nil :background nil :underline t)

;; (global-prettify-symbols-mode -1)  ;; Replace various symbols with nice looking unicode glyphs.

(auto-compression-mode t)       ;; 日本語infoの文字化け防止
(auto-insert-mode t)            ;; auto-insert-mode を有効化
(column-number-mode +1)         ;; modeline に行数と桁数を表示
(delete-selection-mode +1)      ;; リージョンをペースト時などに上書き
(line-number-mode +1)           ;; modeline に行数と桁数を表示
(savehist-mode +1)              ;; コマンド履歴を保存
;; (size-indication-mode +1)       ;; バッファサイズをモードラインに表示
(transient-mark-mode +1)        ;; リージョン内を置換する
(which-function-mode -1)        ;; モードラインにカーソルがある関数名等を表示しない
;; (which-function-mode +1)     ;; モードラインにカーソルがある関数名等を表示する

(if (fboundp 'save-place-mode)
    (save-place-mode +1)        ;; 最後のカーソル位置を記録
  (require 'saveplace)
  (setq-default save-place t))

;; (set-cursor-color "#F58220")
;; (setq blink-cursor-interval 0.5)        ;; カーソル点滅 周期0.5秒
;; (setq blink-cursor-delay 5.0)           ;; カーソル点滅 遅延5秒
;; (setq-default cursor-type 'box)

;; Continue hitting C-SPC and go back to past marks ...C-u C-SPC C-SPC
(setq set-mark-command-repeat-pop t)

;; %Z +900 %Z JST
;; %B February %b Feb
;; %D 02/08/18
;; %Y 2018 %y 18
;; %m 02 %d 08 %e 8
;; %A Thursday %a Thu
;; %R 16:40 %H:%M 16:31 %-I:%M%p 4:31PM
;; (setq display-time-string-forms '((propertize (format-time-string "%Y.%m.%d %H:%M" now) 'face 'bold)))
;; (setq display-time-string-forms '((propertize (format-time-string "%a %Y.%m.%d %H:%M" now) 'face 'italic)))
;; (setq-default display-time-string-forms '((propertize (format-time-string "%H:%M %Y.%m.%d %a" now) 'face 'bold)))
;; (display-time)                          ;; モードラインに時刻を表示させる
;; (display-time-mode t)
;; (display-battery-mode t)
(setq eval-expression-print-length nil) ;; eval結果の表示でリストの要素数を制限しない
(setq eval-expression-print-level nil)  ;; eval結果の表示でリストのネスト数を制限しない

(setq auto-image-file-mode t)           ;; png, jpg などのファイルを画像として表示
;; (setq backward-delete-char-untabify-method 'all)
(setq completion-ignore-case t)         ;; 補完時に大文字小文字を区別しない
(setq comment-style 'multi-line)        ;; C-;(comment-dwim) 複数行に渡るコメントのスタイル
(setq ediff-window-setup-function 'ediff-setup-windows-plain) ;; ediff 時にフレームを使わない
(setq enable-recursive-minibuffers t)
;; (setq eol-mnemonic-dos "(CRLF)")     ;; 改行コードを表示する
;; (setq eol-mnemonic-mac "(CR)")       ;; 改行コードを表示する
;; (setq eol-mnemonic-unix "(LF)")      ;; 改行コードを表示する
(setq frame-resize-pixelwise t)
(setq history-delete-duplicates t)      ;; ヒストリー内の重複を削除する
(setq history-length t)                 ;; t:古い要素を削除しない nn:変数をオーバーライドする
;; (require 'startup.el)
(setq inhibit-startup-screen nil)
(setq initial-buffer-choice t)
(setq initial-scratch-message nil)      ;; 起動時の画面を非表示にする
(setq kill-read-only-ok t)              ;; 読み取り専用バッファーでもカット系でコピー可能
;; (setq kill-whole-line +1)            ;; C-kで行全体を削除する
;; (setq linum-format "%4d " )          ;; 数字の列を揃える
(setq next-line-add-newlines nil)       ;; 最終行へ新たな行追加する
(setq max-lisp-eval-depth 6400)
(setq max-specpdl-size 3200)
(setq process-adaptive-read-buffering t)
(setq read-process-output-max (* 1024 1024)) ;; 外部プロセスから読み取るデータ量の指定（LSP Modeのチューニング）
(setq require-final-newline t)          ;; 常に最後に改行を追加する
(setq ring-bell-function 'ignore)       ;; ビープ音を消す
(setq sentence-end "\\([。！？]\\|……\\|[.?!][]\"')}]*\\($\\|[ \t]\\)\\)[ \t\n]*")
(setq sentence-end-double-space t)
(setq text-quoting-style 'straight)
(setq truncate-lines t)                 ;; 長い行を改行しないで画面外へ伸ばす
(setq truncate-partial-width-windows nil) ;; ウィンドウを左右に分割したときに行を折り返す
(setq user-full-name "TanukiTam")
(setq user-mail-address "tanukitam@gmail.com")
(setq user-login-name "tanukitam")
(setq visible-bell nil)                 ;; Turn off warning sound screen flash
;; (setq window-divider-default-right-width 3)
(setq-default indicate-empty-lines t)   ;; 最終行以降はフリンジにゴミを生やす
(setq-default indicate-buffer-boundaries 'right)
(setq-default line-spacing 0)           ;; 行間スペース
(setq-default transient-mark-mode t) ;; リージョンのハイライト
(setq-default truncate-lines t)
;; ウィンドウを左右に分割したときに行を折り返さない
(setq-default truncate-partial-width-windows t)


;; ダイアログボックスを表示しない
(setq use-dialog-boxn nil)
(defalias 'message-box 'message)
;; スクリーンの最大化
(set-frame-parameter nil 'fullscreen 'maximized)
;; フルスクリーン
;; (set-frame-parameter nil 'fullscreen 'fullboth)
(defun ome-toggle-fullscreen ()
  "Toggle full screen"
  (interactive)
  (set-frame-parameter
   nil 'fullscreen
   (when (not (frame-parameter nil 'fullscreen)) 'fullboth)))


 ;;; 一行が 80 字以上になった時には自動改行する
(setq fill-column 80)
(setq-default fill-column 80)           ;; 長い行を折返す文字列桁数（文字数）
(setq emacs-lisp-docstring-fill-column 90)

;; (setq-default auto-fill-mode t)
;; (add-hook 'text-mode-hook 'turn-on-auto-fill)
;; (add-hook 'org-mode-hook 'turn-on-auto-fill)

;; 無効にする
(setq auto-fill-mode nil)
;; (remove-hook 'text-mode-hook 'turn-on-auto-fill)


;; ;; フリンジのサイズを調整する
;; (fringe-mode '(15 . 10))
;; ;; fringeに表示するマークの形状を変更
;; (setq-default fringe-indicator-alist
;;               (append (list '(continuation . (nil right-curly-arrow)))
;;                       (remove (assoc 'continuation fringe-indicator-alist)
;;                               fringe-indicator-alist)))
;; (define-fringe-bitmap 'right-curly-arrow
;;   [#b00000000
;;    #b00000000
;;    #b00000000
;;    #b00000000
;;    #b01111110
;;    #b01111110
;;    #b00000110
;;    #b00000110])

;; protesilaos
(setq blink-matching-paren nil)         ;; 閉じ括弧を入力しても点滅させない
;; doomemacs
(setq auto-mode-case-fold nil)          ;; ファイル検索を2回行わないようにする
 ;;; 右から左に読む言語に対応させないことで描画高速化
(setq-default bidi-display-reordering nil) ;; 'left-to-right 双方向の並び替えを抑制する
(setq bidi-inhibit-bpa t)               ;; 長い行の双方向スキャン
(setq-default cursor-in-non-selected-windows nil)   ;; フォーカスされていないウィンドウのカーソルを削除
(setq highlight-nonselected-windows nil)    ;; フォーカスされていないウィンドウのカーソルを削除
(setq fast-but-imprecise-scrolling t)   ;; 高速なスクロール
(setq ffap-machine-p-known 'reject)     ;; ドメインにpingを送信しない
(setq idle-update-delay 1.0)            ;; UIの更新頻度を下げる
(setq redisplay-skip-fontification-on-input t)  ;; 不要なフォント表示化を抑制

(cua-mode t)                            ;; cua-mode 矩形選択可能にする
(cua-selection-mode t)                  ;; 標準的Cut&Pasteキー操作エミュレーションを有効化
(setq-default cua-enable-cua-keys nil)  ;; cua-mode そのままだと C-x が切り取りになってしまったりするので無効化

(setq use-short-answers t)              ;; y or n
(fset 'yes-or-no-p 'y-or-n-p)
;; enable y/n answers
(defalias 'yes-or-no-p 'y-or-n-p)     ;; under Emacs27
(fset 'yes-or-no-p 'y-or-n-p)         ;; "yes or no" を "y or n" にする
(define-key query-replace-map [return] 'ack)
(define-key query-replace-map [?\C-m] 'act)


;; バッファ一覧タブ消してくれるので消去
;; モードラインではなく画面上部に表示する
;; (delete (assoc 'which-func-mode mode-line-format) mode-line-format)
;; (setq-default header-line-format '(which-func-mode ("" which-func-format)))

;; バッファのサマリを表示する 関数一覧とか
;; (auto-install-from-emacswiki "summarye.el")
;; (require 'summarye)
;; (se/make-summary-buffer)とか
;; スクロールした際のカーソルの移動行数
;; (setq scroll-conservatively 1)
;; (setq scroll-conservatively 100)
;; (setq scroll-conservatively -1)      ;; スクロールは１行ごとに
;; スクロール開始のマージンの行数
;; (setq scroll-margin 5)
(setq scroll-margin 0)
;; 1 画面スクロール時に重複させる行数
(setq next-screen-context-lines 10)
;; 1 画面スクロール時にカーソルの画面上の位置をなるべく変えない
(setq scroll-preserve-screen-position t)

;; オプションの "Ignore Case for Search" で設定可
;; 検索(全般)
(setq case-fold-search t)
;; インクリメンタルサーチ
(setq isearch-case-fold-search nil)
;; バッファー名の検索
(setq read-buffer-completion-ignore-case t)
;; ファイル名の検索
(setq read-file-name-completion-ignore-case t)
 ;;;置換(全般)
(setq case-replace t)
;; ;; dabbrev 時の置換
;; (setq dabbrev-case-replace nil)

(setq make-backup-files nil)    ;; バックアップファイルの作成実行の有無

;; バックアップファイルの格納ディレクトリーの変更
;; バックアップファイルの作成場所を指定
;;   (対象ディレクトリー . 格納ディレクトリー) のリスト
;; (setq backup-directory-alist '(("." . "~/.emacs.d/backup")))
;; -------------------------------------------
;;  全てのバックアップファイルを/tmp以下に保存する。
;;  http://satosan.jp/CustomizeEmacs.html
;; -------------------------------------------
;; (defun make-backup-file-name (filename)
;;   (expand-file-name
;;     (concat "/tmp/" (file-name-nondirectory filename) "~")
;;     (file-name-directory filename)))

;; 番号付けによる複数保存
;; (setq version-control     t)  ;; 実行の有無
;; (setq kept-new-versions   5)  ;; 最新の保持数 keep 3 backups
;; (setq kept-old-versions   1)  ;; 最古の保持数
;; (setq delete-old-versions t)  ;; 範囲外を削除 delete old backups
```

</details>