2019年11月22日金曜日

Emacs lisp で自分なりに作ってみた、二つ目。

Emacs lisp で、自分なり?に機能を追加してみた、二つ目。 今回は、’org-mode’ のリストで、 ‘checkbox’ をトグル(チェックのオンオフではない)させようとしたもの。

org-mode のチェックボックス付き箇条書きは、たまに、使ってたりしている。 箇条書きにチェックボックスを使う方法は、マニュアルにはあるが、やはり日本語でまとめられているサイトが有り難い。例えば、

とか、感謝だ。

でも、見付けられなかったのが、チェックボックス自体を付与/削除する方法。 私のように右往左往する者にはあると嬉しいのではと思うのだが。 新項目追加なら、’S-M-ret’ (org-insert-todo-heading)、 チェックのトグルなら  ’C-c   C-c’   なのに。

なので、今回挑戦してみた。いつもように、いろんなトコからのコピペ、修正。 なのに、多大な時間がかかってしまった。 もっと、検索に時間をさけばよかったかも。

今回の作業では、’cond’ というのが印象的だったかな。

で、現状、以下。

(defun my-org-toggle-list-checkbox ()
  "Toggle checkbox in org-mode(experimental)."
  (interactive)
  (setq current-line-str
        (buffer-substring-no-properties
         (line-beginning-position)
         (line-end-position))
        )
  (cond ((string-match "^[-+] \\[.\\] " current-line-str)
         (replace-regexp "\\[.\\] " "" nil
                         (line-beginning-position)
                         (line-end-position)
                         )
         )
        ((string-match "^[-+] " current-line-str)
         (replace-regexp "^[-+] " "- [ ] " nil
                         (line-beginning-position)
                         (line-end-position)
                         )
         )
        (t
         (beginning-of-line)
         (insert "- [ ] ")
         )
        )
  )

空白の処理とかを追加できたら、とか思うが、 きっと、スマートで、ちゃんとした奴が既にあるだろうから、また時間をみて探してみよう。

まあ、なんとか動いているようなので、とりあえず良しかも。

2019年11月5日火曜日

サイコンを交換(新調)した

サイコンが時々止るようになって、2年ほどが経過してしまったが、やっと、サイコンを新調した。 現在のメインバイクではなく、街乗りメインになってしまったMTB用。

新しいモデルは、 Cat Eye Enduro CC-ED 400 というやつで、 ワイヤードのタフネスモデル。アナログ人間なんで。

キャットアイの海外モデルで、国内への展開は無いみたいで、 海外通販を利用するタイミングを待っていた、といかんじ。タイヤと一緒に購入。

これまで使ってたのは、古い古い Enduroモデル(CC-ED300) で、 10年ほどの時代差だ。

並べるとみる。

本体が少々大きくなり、画面や文字も見易くなった。

ケーブルは随分と太くなった。

基本機能はしっかり揃っていて、不満があるはずもなく、長い付き合いになって欲しいと願うばかり。

2019年10月8日火曜日

python prompt-toolkit で簡単なメニュを造りたい

自分でちょっとずつ作っている cuekoma(python) は、年に数回しか使わない。 たぶん、そんな理由で、今年の秋のツーリング準備で使おうとしたら、使い方を忘れていた。 健忘症なのか痴呆症なのか。

コードを読んだりしてる時間が結構無駄。 なので、少しメニュー化することを真剣に考えようと思った次第。

が、今回は間に合うわけもないので、雛形だけ作ってみた。 省メモリ、省codeにしたいので、いわゆる、GUI のメニューでは無い。 しかも、ダイアログなんかも使わないシンプルなやつ。

やりたい事は、

  1. スクリプトを走らせると、
  2. 簡単な概要を表示して(configparserではない)、
  3. ジョブを選択して、
  4. 必要な設定ファイルを選択して、
  5. 実行する。

という、単純なもの。なにげに、 MS-DOS を思い起させるヤツだ。

使ったのは、 python-prompt-toolkit で、html のような設定で色付けとか、太字とかも可能。そして、logzero と使い分けることも。

現状は以下。

稚拙な source が下。

#!~/.pyenv/shims/python
"""Viking data file handling tool."""

from __future__ import unicode_literals

import os
import sys
import logging
from pathlib import Path

import logzero
from fuzzyfinder import fuzzyfinder
from prompt_toolkit import HTML, prompt
from prompt_toolkit import print_formatted_text as pprint
from prompt_toolkit.history import FileHistory
from prompt_toolkit.completion import Completer, Completion, WordCompleter
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.formatted_text import FormattedText

# script run path
os.chdir(Path("~/Documents/proj/gpxs").expanduser())
# the Python 3.6 or above, os.chdir() can deal with Path object directly.

LOG_FORMAT = "%(color)s[%(module)s:%(lineno)3d]%(end_color)s %(message)s"
FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
logzero.setup_default_logger(formatter=FORMATTER)
logzero.logfile("./_logs/pp-menu.log", maxBytes=3e5, backupCount=3)
logzero.loglevel(logging.DEBUG)

def get_keypars(key_par, in_buf, key_nam):
    """Parse key parameters of this application."""

    if in_buf[0] != "#" and in_buf[0] != "\n":
        if in_buf[0] in ["["]:
            key_nam = in_buf.split("[")[1].split("]")[0]
            if key_nam not in key_par.values():
                key_par[key_nam] = {"cate": key_nam}
        else:
            key_par[key_nam][in_buf.split("=")[0].strip()] = in_buf.split("=")[
                1
            ].strip()

    return key_par, key_nam


def read_ppmenu_ini(ini_f):
    """Read script setting ini file."""

    with open(ini_f, "r") as in_file:
        key_par, key_nam = {}, ""
        for in_buf in in_file:
            key_par, key_nam = get_keypars(key_par, in_buf, key_nam)

    return key_par


def show_app_para(app_parm):
    """Show script parameters and description."""

    _str = "run  dir : %s " % str(Path.cwd().relative_to(Path.home()))
    pprint(HTML(' - <skyblue>%s</skyblue> (application\'s ini file is hear)' %  _str))

    tour_path = Path(app_parm["app"]['top_dir'])
    _str = "data dir : %s " % str(tour_path.relative_to(Path.home()))
    pprint(HTML(' - <skyblue>%s</skyblue> (user\'s data(in/out) directory.)' %  _str))

    _str = "co_poi.vik : 個人的なPOIを収めている viking のデータファイル."
    pprint(HTML('\n - <skyblue>%s</skyblue>' %  _str))
    _str = "\n  簡単な説明を付け加えておく方が良いと、後悔している。\n"
    pprint(HTML('             <skyblue>%s</skyblue>' %  _str))


class MyfileCompleter(Completer):
    """Set Completer."""

    def __init__(self, globbed_path):
       self.globbed_path = globbed_path
       self.inifile_list = [f.name for f in self.globbed_path.glob("*.ini")]
       self.num_setfile = len(self.inifile_list)

    def get_completions(self, document, complete_event):
        """Set Completer."""
        word_before_cursor = document.get_word_before_cursor(WORD=True)
        matches = fuzzyfinder(word_before_cursor, self.inifile_list)
        for m in matches:
            yield Completion(m, start_position=-len(word_before_cursor))


def select_ini_file(globbed_path):
    """Select tour ini file."""

    _s_text = FormattedText([
        ('#cccccc bold', "- Select ini file. "),
        ('#9999cc', '( %d ini files in dir.)\n' % MyfileCompleter(globbed_path).num_setfile),
        ('#7766cc', "   (<tab>key show list)\n  >  "),
    ])

    user_input = prompt(
        _s_text,
        history=FileHistory('pp-menu-ini-history.txt'),
        auto_suggest=AutoSuggestFromHistory(),
        completer=MyfileCompleter(globbed_path),
    )

    _s_text = FormattedText([
        ('#d15fee italic', '  >> INI file : '),
        ('#e066ff', user_input),
        ('#d15fee italic', '.\n'),
    ])
    pprint(_s_text)

    return Path(globbed_path / user_input)


def select_job_category():
    """Select job."""

    job_list = [
        "10: co-poi.vik (change waypoint symbol to default)",
        "11: co-poi.vik (re-build from vildata. require co_poi_lay.set)",
        "12: co-poi.vik (copy to custom POI dir. require to_garmin_poi.set) ",
        "13: conv. to vildata, from all gpx  data(check ...)",
        "14: conv. to vildata, from all json data(check ...)",
        "99: quit",
    ]
    job_index = [int(x.split(':')[0]) for x in job_list]

    _job_list_text = '\n   ' + '\n   '.join(job_list) + ''

    _s_text = FormattedText([
        ('#cccccc bold', '- Select job : \n'),
        ('#7799dd', _job_list_text),
        ('#7766cc', "\n\n   <tab>key select from list."),
        (' ', '\n\n  > '),
    ])

    job_completer = WordCompleter(job_list, ignore_case=True, )
    user_input = prompt(
        _s_text,
        history=FileHistory("pp-menu-job-history.txt"),
        completer=job_completer
    )

    _s_text = FormattedText([
        ('#d15fee italic', '  >> JOB: '),
        ('#e066ff', user_input),
        ('#d15fee italic', '.\n'),
    ])
    pprint(_s_text)

    job_number = user_input.split(':')[0]

    if int(job_number) not in job_index:
        # while でループへ。
        logzero.logger.info("!! select wrong job !!")
        sys.exit()

    if int(job_number) == 99:
        pprint(HTML('\n<b> * ばいばい *</b>\n'))
        sys.exit()

    return job_number


def main():
    """Read config and set and select select job."""

    pprint(HTML('\n<b><i>* menu test using python prompt toolkit .............</i></b>\n'))

    # スクリプトの共通パラメタの読み込み
    ppmenu_ini_file = Path.cwd() / "pp-menu.ini"
    app_parm = read_ppmenu_ini(ppmenu_ini_file)
    show_app_para(app_parm)

    # ジョブの選択
    job_number = select_job_category()

    # 個別設定ファイルの選択
    globbed_path = Path(app_parm['app']['top_dir'])
    tour_setfile = select_ini_file(globbed_path)

    logzero.logger.info(tour_setfile)
    logzero.logger.info(job_number)


if __name__ == "__main__":
    main()
    sys.exit()

年末にかけて、ちょっとづつ進めようと思っている。 メニュー化で整理しようとすると、色々、`あれ` という事が噴出してるから。

Emacs の window レイアウト をショートカットで

emacs を使っていて、dired とかでファイル操作を行なう時、 windowを複数並べて作業するのだが、この状態にするのが面倒だと感じている。 で、いつものように、コピペメインで、hydraのメニューに追加してみた。

やった事は、

  1. window をカレント一つにしてから
  2. 現在編集中のファイルを左右に分割し
  3. 他方に移動して、既定のdirectory を dired で開く。
  4. さらに、上下に分割して、
  5. counsel-bookmark を実行

というもの。当然、元ネタがあるわけで、 Using display-buffer-alist « Simplify d.o.o. という記事に出会ったから。

こいつを、ほんのチョット変更して組み込んだだけ。以下。

(defun my/work-lay(image-dir)
  "Split windows for image-file handling."
  (interactive)
  ;;
  (when (/= (count-windows) 1)
    (delete-other-windows)
    )
  ;; Create new window right of the current one
  (split-window-right 102)
  ;; Go to next window
  (other-window 1)
  ;; open image stocked directory
  (find-file image-dir)
  ;; Create new window below current one
  (split-window-below)
  ;; Go to previous window
  (other-window 1)
  ;; select bookmark
  (counsel-bookmark)
  )

これを、hydraのメニューに以下のようなアイテムを追加して終了。

("w1" (my/work-lay "~/Documents/ownCloud/imag") "work-org")
("w2" (my/work-lay "~/Documents/ownCloud/hugo") "work-hugo")

まだ自分にすら馴染んでない。きっとアップグレードするとか、別の手段に移行することになるかと。少しづつ、少しづつ。

自転車のビンディングシューズ、購入

ビンディングシューズを購入した。

インナーがボロボロで、ロングだと痛くなる。この状態で、ごまかしながら1年使ったが、 そろそろいいんじゃない?ということで、 誕生日(うれしくないけど)だという言い訳で、購入を決めた。 しかし、高くなってるなあ。

自分には Northwave (代理店 ウインクレル株式会社) が 結構合っていて、今回4足め(サンダル込み)。通販で購入するのも、そうゆう理由から。ビンディングはShimanoのSPD。

購入できるものを纏めると、以下。

  • グレードというか、価格というか
    • XCは、 origin < razer < revel < ghost < extreme
    • AMは、 escape Evo < outcross < spider2plus < enduro MID

これまで使っていたやつは、XCの一番底辺のグレード。さすがにカタログには無い。 きっと、origin が相当すると思う 今回は、AMにした。年齢的にも用途からも、フラペ対応が必要だろうというのが理由。悩んだけど。

カタログに、「ペダルの力がかかる部分を硬く、土踏まず部分は柔軟に」とあったので、 ビンディングからの突き上げ感対策をになっているにちがいないというのが決め手。 「28%耐磨耗性に優れる」ミシュランのソールにも興味だ。

定価は 168 で、あまぞんで 173だ。外通だと、70〜80ユーロぐらい。サイズによって値段が変ったりする。 貧乏人は当然、外通。

開封して、ぱっと見の印象は、かなりしっかり、つまり堅そう。

これまで使ってたヤツと並べてみる。

  • まず、散歩に使った印象

    足首というか踝まわりのサポートが無いハイキングシューズ。 ソールは堅く登山靴に近いかも。スニーカーとはいえない。包み込むようなホールド感も弱い。

    これまでとは足型が異なるようで、ワイド。もう半サイズ小さくても良かったかもと思うが、ハーフサイズの展開は無い。

    シマノのワイドぐらいはあるかもしれない(過去に一度経験)。足の指が動かせる。薄手の靴下は止めた方がよさそう。 夏場は困るかもしれない。

    ラバーソールなので、やはり重量はある。

  • 100キロほどのライド(3回)。

    ソールはしっかりしていて、SPDの突き上げを「点」で感じるのは僅か。カタログにあるように、きちんと補強されていると思う。使い込んでも継続するかは、少々不安。

    ベルクロの締め付け調整というか、足の甲まわりをフィットさせるのが難しい。 足型が異るようで、甲まわりの断面形状が、これまでをΩ型とするなら、今回は半円とう感じ。 足型によっては苦労するのかもしれない。 まあ、これまで使ってたやつも、最初はなじみが悪かったと記憶してるので、 素材が柔らかく馴染むのを待とう。

    ペダル(DIXNA FP、スポットクリップレスペダル、片面フラット)との相性が良いのか、ペダル上の安定感(内外への踏ん張り感)が良い。 しかもフラット面とクリップ面との差が小さくなるのが結構有難かったりする。

    ただし、ダイレクト感は、これまでより劣る。

    靴の中で、足首の方はある程度固定されるが、爪先の方は少し動かせるぐらいの余裕がある。で、 爪先側を動かしてペダルの踏み具合に変化をつけることが可能みたい。ちょっと新鮮で意外。

    気温30度ぐらいなら、我慢できないような蒸せは感じない。

    インソールを交換。これまで使ってた(Super feet 6年ほど使用)のを移植。通気性は悪くなるが、安定感は増す。

    まだまだ、クリート位置の調整中。

まあ、馴染んでくるまで、1年ぐらいはかかりそうなので、気長に付き合おうと思う。

2019年9月17日火曜日

Emacs の hydra で、ちょっとした変更

Emacs の設定に、 hydra を使っていて、物覚えの悪い頭の補助をしてもらっている。

justbur/emacs-which-key も入っているが、メニューというより、確認という位置付けかと。

下が自分の基本パターン?になるかも。

(defhydra hyd-flyck (:hint nil :exit nil)
  "Flycheck"
  ("M" flycheck-manual "Manual" :column "flycheck")
  ("v" flycheck-verify-setup "verify setup")
  ;;
  ("p" flycheck-previous-error "prev" :column "Errors")
  ("n" flycheck-next-error "next")
  ("c" flycheck-buffer "check buf")
  ("l" flycheck-list-errors "list")
  ;;
  ("?" flycheck-describe-checker "describe" :column "Checker")
  ("d" flycheck-disable-checker "disable")
  ("m" flycheck-mode "mode")
  ("s" flycheck-select-checker "select")
  ;;
  ("q" nil "Exit" :exit t :column "Quit")
  ("." nil "cancel" :exit t)
  )

で、あまり見掛けないけど、結構いいかも、という設定に出あったりする。 まあ、ドキュメントに記載されているはずだが、コピペメインの私が読んでいるはずもない。

  • ショートカットキーを2文字以上にする

    自分は、勝手にワンキーだと思い込んでいた。他のhydraに飛ばなくても、階層化っぽくなる。

    セカンドキー以降は、ミニバッファ下にメニュが表示されるので、不細工ではあるが、キー不足対策や、カテゴライズに重宝かも。

    例えば、ブックマークについて、以下のようにしてみている。主にバッファ内利用をメインにしている、 joodland/bm を使っているが、サブ的に標準のbookmarkを追加してみた。

    あと、削除関連は複数キーにして、打ち間違い対策としてみた。

    あと、デフォルトでキーバインドされてるのは、それをイメージできるようにしておけば、いずれ hydra には不要になるかも、と思ったりする。

    (defhydra hydra-bkmk (:color pink :hint nil)
      "BookMark(bm/buildin)"
      ("m" bm-toggle "toggle" :column "marked")
      ("N" bm-lifo-next "LIFO N")
      ("P" bm-lifo-previous "LIFO P")
      ;;
      ("n" bm-common-next "next" :column "jump")
      ("p" bm-common-previous "prev")
      ("l" bm-show-all "list o/w")
      ;;
      ("s" bm-toggle-buffer-persistence "stay(toggle)" :column "edit")
      ("rr" bm-remove-all-current-buffer "remove c.buff")
      ("rR" bm-remove-all-all-buffers "remove a.buff")
      ;;
      ("aa" bm-bookmark-annotate "annotate" :column "annotate")
      ("aA" bm-bookmark-show-annotation "show anno")
      ;;
      ("xrl" bookmark-bmenu-list "blist" :exit t :column "Standard BkMk")
      ("xrm" bookmark-set "set current" :exit t)
      ("bo" bookmark-jump-other-window "jump other" :exit t)
      ("bc" counsel-bookmark "counsel bkmk")
      ("br" counsel-mark-ring "counsel mk ring")
      ;;
      ("q" nil "quit" :color blue :column "Quit")
      ("." nil "quit" :color blue)
      ("U" org-ctrl-c-ctrl-c "org ctl cc")
      )
    
  • “:pre” とか “:post” とか

    メニュー自体、メニューの項目が起動する前後での処理を追加できる。ようだ。

    New in Hydra - :pre and :post clauses を参考に(少し古いかも) 試してみたのが以下(20190821.939)。正しいかどうか不明。動くのだが、違和感がある。

    (global-set-key
     (kbd "C-z")
     (defhydra hydra-vi
       (
        :body-pre
        (progn (set-cursor-color "#2080d0") ;; このメニュー起動時
           (message "start menu"))
        :pre
        (progn (set-cursor-color "#40e0d0") ;; 各コマンドの前
           (message "in menu"))
        :after-exit
        (progn (set-cursor-color "#ffffdd") ;; コマンドの後 ?
           (message "agter exit"))
        :post
        (progn (set-cursor-color "#ffccff")  ;; このメニュー終了時 ?
           (message-box "!! This is test menu !!\n"))
        )
       "vi like cur move key"
       ("l" forward-char)
       ("h" backward-char)
       ("j" next-line)
       ("k" previous-line)
       ("C-n" previous-line) ;; これが有効になる
       ("q" nil "quit")
       )
     )
    
  • 単純な、羅列

    以下は4列表示。ファイルのリンクを並べたてようとした時に出会った。

    (defhydra hyd-open-tfile (:hint nil :columns 4)
      "open target file(default is orgfile)"
      ("d" (my-targetfile-open  1) "todo")
      ("m" (my-targetfile-open 12) "memos")
      ("b" (my-targetfile-open  2) "bike_memo")
      ("p" (my-targetfile-open 14) "python")
      ;;
      ("g" (my-targetfile-open  4) "diag_samp")
      ;;
      ;; (中略)
      ;;
      )
    

他にも色々ありそう。しかし、設定ばかりに手間かけると、 他が疎かになてしまう。反省。

2019年9月13日金曜日

Emacs の replace を見直してみた

今まで、replaceは正直、それほど使ってなかった。ましてや一括置換なんて怖くて。

なので、color-moccur で検索して、moccur-edit で周辺を確認しながら編集だった。 さすがに数が多いとたまらないので、少しは使えるようになればと思った次第。

いつものようにコピペ主体の設定。 参考にさせて頂いたサイトは、

で、使ってみようとしているのは以下。 これまでは、color-moccur のみ設定していた。

  • 標準の query-replace を emacs-anzu で。 migemo 対応。 一番簡単なコマンドだけ使ってみる。

    (use-package anzu :ensure t
      :config
      (setq anzu-use-migemo t)
      (setq anzu-minimum-input-length 2)
      (setq anzu-search-threshold 1000)
      (global-anzu-mode +1)
      )
    
  • 今迄と同じ color-moccur。遅いけど、これも migemo に対応している。

    (use-package color-moccur :ensure nil
      :demand
      :commands (isearch-moccur isearch-all)
      :init
      (setq isearch-lazy-highlight t) ;; original t
      :config
      (setq *moccur-buffer-name-exclusion-list*
        '(".+TAGS.+" "*Completions*" "*Messages*"
          ".bbdb" "\\.mypy_cache"))
      (setq moccur-split-word t) ;; original nil
      (setq dmoccur-use-list t)
      (setq dmoccur-use-project t)
      (setq moccur-use-migemo t)
      )
    

    どうも、私の稚拙な設定では、imenu-anywhere とバッティングするようで、用途が広そうな、color-moccur を優先し、 imenu-anywhere を無効化している。org だけなら、counsel-org-goto-all だが。

  • あったけど、使ってなかった swiper-query-replace。 swiper で絞り込んだ状態にして `M-q` で query-replace する。

    特に新しい設定はしてない。単に知らなかっただけ。

新しいやつらは3つ。

  • anzu-query-replace
  • vr/replace
  • vr/query-replace

これに、moccur を加えて hydraの検索関係メニューに追加した。
ivy と併せて replace を意識してみる。

さて、どうなることか。

2019年9月8日日曜日

Emacs lisp で始めての自分なり(ではなかったrefileの)カスタマイズ?

Emacs lisp で、自分なり機能追加、みたいな真似事をやってみた。

自分で学んでやったことは、ほんの僅か。インターフェースとかを組み合わただけだが、なんと時間のかかったかこと。

きっかけは、 org-refile の初回起動が遅くて、イラッとするので、少しぐらい改善できたら、と思ったから。

パソコンが遅いのもあるが、 refile先を細かく分けたからだと思う。ちなみに、NAS へ置いてあるファイルを加えると、たまらなく遅い。

[20191015] 例えば、ここなど、かなり よさそう。最初に読んでいれば、違った方法をやったかも。

やったこと。やろうとしていること。

  • refile に使うファイルはたいがい決ってるので、事前登録しておく。
  • このファイルを指定して、 `other-window` で開く。
  • プレビュとかで移動先を確認する。
  • カーソルを元に戻して、リファイル(avy-org-refile-as-childを使ってみる)。

NAS上のファイルへのアクセスも選択的になる。当然、全部は無理なので、 avy-org-refile-as-child までの操作を hydra との組み合わせでやってみた。 bookmark をうまく使えばいいじゃない、という思いもあったが一度やってみてもと思った。

プレビュで、 owdrive で other-window 操作しようと思ったが、ターゲットのorgファイルがfoldで開く設定にしているので止めた。その替りに、hydra メニューに outline-minor-mode の項目を追加してみた。

取り敢えず動いたという感じ。

本当にこんなのが必要なのかは、使ってみてからなのだが、今のところ、 `boolmark-jump-other-window` と `avy-org-refile-as-child` を組合せるだけで十分だったかも。ただ、ショートカットでファイル選択は、いいかも、という印象。できれば、 開き直しに対応させたいが、ハードル高そう。

hydra を含めた全体は以下。実際のターゲットファイルは18個と多い。絞り込めるか。

  (setq tflist '("captured.org"       ;; 0
                 "todo.org"           ;; 1
                 "bike_memo.org"      ;; 2
                 "cuekoma.org"        ;; 3
                 "emacs_memo.org"     ;; 4
                 "linux_memo.org"     ;; 5
                 "python.org"         ;; 6
                 "memos.org"          ;; 7
                 "raspi_memo.org"     ;; 8
                 ))
  ;;
  (defun my-targetfile-open (n)
    "open target file other windows"
    (interactive)
    (setq targetfile
          (concat "~/Documents/ownCloud/" (nth n tflist)))
    (find-file-other-window targetfile)
    ;; (other-window -1) ;; 直前に戻る
    (message "open target file : %s" targetfile)
    )
  ;;
  (defhydra hyd-opentartget (:pre (progn
                                    (bm-toggle)
                                    (hl-line-mode 1)
                                    )
                             :post (progn
                                     (bm-toggle)
                                     (hl-line-mode -1)
                                     (other-window -1)
                                     )
                             :hint nil)
    "open target file"
    ("t" (my-targetfile-open  1) "todo.org" :column "agenda" :exit t)
    ("m" (my-targetfile-open  7) "memos.org" :exit t)
    ("b" (my-targetfile-open  2) "bike_memo.org" :exit t)
    ("p" (my-targetfile-open  6) "python.org" :exit t)
    ;;
    ("e" (my-targetfile-open  4) "emacs_memo.org" :column "regular")
    ("r" (my-targetfile-open  8) "raspi_memo.org" :exit t)
    ("l" (my-targetfile-open  5) "linux_memo.org" :exit t)
    ;;
    ("J" (forward-line 1)    "next line" :column "OL move cursor")
    ("K" (forward-line -1)   "previous" )
    ("U" (scroll-up 5)       "sc up 5" )
    ("D" (scroll-down 5)     "sc dn 5" )
    ;;
    ("N" outline-next-visible-heading "next head")  ;; Next
    ("P" outline-previous-visible-heading "prev head") ;; Previous
    ;; ("}" outline-forward-same-level "f same")   ;; Forward - same level
    ;; ("{" outline-backward-same-level "b same")  ;; Backward - same level
    ("T" (beginning-of-buffer 0)   "top" )
    ("G" (end-of-buffer 0)         "bottom" )
    ;;
    ("M" outline-show-all "show all" :column "ol show")
    ("T" outline-show-entry "show this")
    ("S" outline-show-subtree "show below all")
    ("X" outline-show-children "show child")
    ;;
    ("Z" outline-hide-subtree "hide below" :column "ol hide")
    ("F" outline-hide-body "hide body")
    ("C" outline-hide-entry "hide this")
    ("O" outline-hide-other "hide others")
    ("H" outline-hide-leaves "hide bellow body")
    ;;
    ("q" nil "Exit" :exit t :column "Quit")
    ("." nil "cancel" :color blue)
    )

2019年8月29日木曜日

Emacs の ox-hugo で HUGO を (2)

org-mode の babel(org-src) で PlantUML のスクリプトを記述して、ox-hugo で Hugo に反映できるかやってみた。

  • まず、emacs で plantuml-mode をインストしておく。

    (use-package plantuml-mode :ensure t
      :mode (("\\.plantuml\\'"  . plantuml-mode)
             ("\\.ptuml\\'" . plantuml-mode))
      :config
      (setq plantuml-jar-path (expand-file-name "~/bin/plantuml.jar"))
      (setq plantuml-exec-mode '(jar))
      )
    
  • 次に、org-mode の babel で plantuml を有効にしたりする。

      (use-package ob :ensure nil :after org :demand
        :config
        (setq org-confirm-babel-evaluate t)  ;; 実行は確認してから
        ;; = blockdiag
        (use-package ob-blockdiag :ensure t :demand :after ob)
        ;; = mermaid
        (use-package ob-mermaid :ensure t :demand :after ob
          :mode  ("\\.mmd\\'" . mermaid-mode)
          :config
          (setq ob-mermaid-cli-path "/home/ほげ/.yarn/bin/mmdc")
          )
        ;; = plantuml
        (setq org-plantuml-jar-path (expand-file-name "~/bin/plantuml.jar"))
        ;;
        ;; = gnuplot これをインストしないと動かなかった。 [2019-08-13]
        (use-package gnuplot :ensure t :demand  :after ob)
        ;;
        ;; = active Babel languages
        (org-babel-do-load-languages
         'org-babel-load-languages
         '((R          . t)
           (emacs-lisp . t)
           (awk        . t)
           (shell      . t)
           (python     . t)
           (perl       . t)
           (dot        . t)
           (gnuplot    . t)
           (ditaa      . t)
           (mermaid    . t)
           (plantuml   . t)
           ))
        ;;                  ;
        (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
        (add-to-list 'org-src-lang-modes '("diag" . xdiag)) ;; blockdiag
        (add-to-list 'org-src-lang-modes '("mermaid" . mermaid))
        (add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
        (add-to-list 'org-src-lang-modes '("gnuplot" . gnuplot))
        )
    
  • hugo の org file での記述は以下。both が code なら、コードだけ。 `:exports` の オプションは、code, results, both, none。

        #+caption: plantuml test code 00
        #+name: plantuml-code-00
        #+BEGIN_SRC plantuml :file plantuml_test1.png :cmdline -charset UTF-8 :exports code
        @startuml
        class Foo1 {
          複数行に
          対応している。
          ..
          as you want
          and group
          ==
          things together.
          __
          You can have as many groups
          as you want
          --
          End of class
        }
    
        class User {
          .. Simple Getter ..
    ​      + getName()
    ​      + getAddress()
          .. Some setter ..
    ​      + setName()
          __ private data __
          int age
          -- encrypted --
          String password
        }
        @enduml
        #+END_SRC
    
        #+CAPTION: plantuml test 01 result
        #+RESULTS:
        [[file:plantuml_test1.png]]
    

    caption の使い方が良く解らない。 both にしたときの、result のキャプション指定が別らなかった。とりあえず、code にして、手作業で指定。 blogg的な使い方なんで、キャプション抜きでよいか。

    あと、hugo での build も、 shell ではなく、 org-babel で行うようにした。 hugo は早いけど、やはり十数秒必要なので、オプションで `:async` を設定してみた。 (万能ではないので、動作確認が必要みたい)

        #+BEGIN_SRC shell :async
        cd ~/Documents/mup/hugo; hugo
        #+END_SRC
    

画像の作成は、sphinx のように、ビルダー側でなく、 emacs 側でハンドリングするので、他のスクリプトも、emacs で作業できるなら、 使えるということだろう。当たり前か。

しかし、postが少し増えると、ファイルがすぐに大きくなるので、 org-refile や org-archive なんかが頻繁に必要になるかもと思う。個別ファイルの方が良かったかも。杞憂?

org-refile は、起動に時間がかかるので、avy-org-refile-as-child が使えないかと...

2019年8月23日金曜日

khal のデータファイルを org に変換してみた

日頃、作業とかポタリングとかのスケジュール管理に、 khal(GitHub) を使っている。

データは手元のパソコンに保存されていて、 45分毎に、ラズパイで稼動させている DAViCal (CalDAV servers) と Google との三者を vdirsyncer で同期させている。

予定管理自体を、emacs で行うことは諦めていたのだが、 今更だが、 khal の一覧機能が不満なので、 emacsで管理するのではなく単に一覧を表示する だけなら、 出来るかもと考えた次第。

結果はこんな感じ。自転車とゴミ出しだけだが。

最近はこうなってる(201911)。

python のスクリプトを、 emacs から起動して、 以下の関数を用意して、 `<f2>-K` で 出来上がったファイルを read only で og-agenda-list を開くようにしてみた。

(defun my-khal2org ()
  "Convert khal ics file to org file."
  (interactive)
  (let* ((exepath (expand-file-name "~/Documents/proj/icaltools")))
    (shell-command-to-string (concat "cd " exepath "; python khal2org.py"))
    ;; (find-file-read-only-other-window (expand-file-name "~/Documents/ownCloud/khal.org"))
    (org-agenda-list) ;; org-agenda を起動するようにした(201911)
  ))

pythonのスクリプトは、 icalendar(GitHub) というライブラリを使ったのだが、 いつもの様に、このドキュメントだけでは私には無理なので、 ical2org-two(GitHub) のソースを参考に、 粛々とコピペ修正作業。

まあ、無くても良いが、有ってもよいかな、というレベルか。 カテゴリや期間をemacsから指定できるようにしてみたいが、道は遠そうだ。

2019年8月12日月曜日

Garmin の 心拍計を装着するチェストベルト交換

Garmin の心拍計のチェストベルトを交換した。 今回が3本めだったような記憶だが、破断は始めてだと思う。 装着していて、突然切れた。これまではゴムが伸びて交換だったはず。

今回は、正規品が高価なので、互換品を試すことにした。例えばamazonで比較すると以下。 当然というか、CATEYE にした。

センサーは、電池の蓋にあるパッキンが怪しくなってきてるような古いやつ。 ベルトに取り付けると、装着面がフラットにならない。 気になる人にはダメかもしれない。

ベルトの接続部はこのような、ひっかけるタイプなので、これには注意が必要。 「ゆるゆる」に装着していて外れることがあった。 ジョイントのセンサー側が上になるようにして「ゆるゆる」にせず試してみている。

最近、測定データが実感と異なると感じることが多々あったが、 センサーではなく、ストラップの導電性の問題だったのかもしれない。 交換した後は安定してるように思う(ふらしぼ?)。
特に夏場は、心拍数から休息時間を考えて、 熱中症とかポックリとか気に掛けるようにしてるので、 実は「やば」かったのかも。

今のところ、安定して使えているので、まあ満足。

2019年8月3日土曜日

Emacs と Vim で ちょっとしたメモを共有したい

Emacs と Vim で ちょいとしたメモを共有しようとやってみた。 けっしてスマフォとの共有ではないし、 書捨てで良いようなメモを、という位置付け。

emacs では org-mode をメインにしているが、 org-mode は emacs環境限定?なので、 常に emacs を起動している訳ではない自分は、 ちょいっとメモ、ができない状況が時々ある。

そんな時、簡単にメモる手段が欲しくて、 terminalで mattn/memo(Github) + fzf + vim を使っていた。 jrnl とか、 khal をメモに、 とか試したが、結局こいつに落ち着いていた。

で、これらのメモを emacs で扱えないかと考えた次第。

めもしたものは、markdown ベースなので、 手間を惜しまなければ問題はないが、 そこは、なんぞ方法があるに違いないと探してみた。 今回使ったみたのは、Deft for Emacs

mattn/memo(Github) と共有させるため、 既存ファイルの format を修正する手間が必要だったが、 なんとなく、org配下で扱えるようになったかも、と思う。

  • Deft for Emacs の設定

    保存は、org-directory下にした。 deftでは、以下の操作ができる。

    • rename (C-c C-r)
    • delete (C-c C-d)
    • New (C-c C-n)
    • archive (C-c C-a)
    • quit (C-c C-q)

    archiveはサブディレクトリがデフォルト。 org-captureの設定もしたが、必要なかったように思う。

    絞り込み操作が、ivyになってないのは少し残念。

  • ;; deft
    (use-package deft :ensure t
      :bind ("<f7>" . deft)
      :commands (deft)
      :config
       (setq deft-directory "~/Documents/ownCloud/_posts"
       deft-extensions '("md" "org")
       deft-auto-save-interval 3.0
       deft-use-filename-as-title t)
     )
    
    ;;
    (defun my/generate-md-memo-name ()
      (setq my-org-note--name (read-string "Name: "))
      (setq my-org-note--date (format-time-string "%Y-%m-%d"))
      (setq my-org-note--dtime (format-time-string "%Y-%m-%d %H:%M"))
      (expand-file-name (format "%s-%s.md" my-org-note--date my-org-note--name) "~/Documents/ownCloud/_posts"))
    ;;
    
    ;; org-capture
     ; .......
      ("n" "note(mkd)" plain
     (file my/generate-md-memo-name)
     "%(format \"---\ntitle: %s\ndate: %s\n---\n\n# \" my-org-note--name my-org-note--dtime)%?")
     ; .......
    
  • memo の設定

    • `~/.config/memo/config.toml`

      memodir = "~/Documents/ownCloud/_posts"
      memotemplate = "~/.config/memo/template.txt"
      editor = "nvim"
      column = 26
      selectcmd = "fzf"
      grepcmd = "ag ${PATTERN} ${DIR}"
      assetsdir = "."
      pluginsdir = "~/.config/memo/plugins"
      templatedirfile = ""
      templatebodyfile = ""
      
    • `~/.config/memo/template.txt`

      ---
      title: {{.Title}}
      date: {{.Date}}
      ---
      
      # {{.Title}}
      

左が、emacsのdeft、で右が memo + fzfl。

メモファイルを org 配下に置くので、 deadgrep,counsel-rgとかの検索対象になるから、大きなメリットにならないかもしれないが、 スコープを限定したハンドリングが可能になったのはひとつ前進だと思っている。
暫く放置して、様子見。

2019年7月26日金曜日

Emacs org-capture で サブメニュー

以下のサイトによると、 org-mode の キャプチャでサブメニュが使えるという。 マニュアルにあるという。まあ私が読むはずもないが、 と思って見てみたが記載は見当たらなかった。emacsのhelpの方にはある。 (`<f1> org-capture-templates`)

Emacs oeg-mode は使ってるが、org-capture 積極的に使っているとはいえない。 ジャンプして書き込みすればよい、という感じ。

だが、キャプチャメニュにサブが指定できるのなら、細かく対応させれば、メニューすっきり、便利かもしれない。

まだ、設定に間違いがあるみたいで、Abortでエラーがでるけど、気にしない。

  • キャプチャメニュ(`...`がサブメニュあり)
  • サブメニュ

視認性は良くないが、キーを覚えれば問題なさそう。 少し使ってみようと思う。

2019年7月16日火曜日

Emacsでformatterを試してみる

Emacs上で、コードの整形をやってくれる、formatterの設定をやってみた。

pythonについては、なんとなく塩梅が分るようになった気がしているが、その他は全滅なので HUGO を触るのに不便に感じたのでやってみた。

試したのは、 format-all、 prettier、 js-beaytify。

prettier と js-beaytify では、prettierの方がメジャーみたい。

1 prettier

  • GitHub - prettier/prettier-emacs: Minor mode to format JS code on file save

  • 対応しているのは、 flow、babylon、typescript、css、less、scss、json、json5、json-stringify、 graphql、markdown、mdx、vue、yam、html など。

  • save する時に自動でやると、反応が遅いので、不快になる。

    (use-package prettier-js :ensure t :defer t
     :diminish (prettier-js-mode . "-prett")
     ; :hook (
     ;   (yaml-mode . prettier-js-mode)
     ;   (json-mode . prettier-js-mode)
     ;   (html-mode . prettier-js-mode)
     ;   (web-mode . prettier-js-mode)
     ;   (css-mode . prettier-js-mode))
     :config
      (setq prettier-js-command "~/.yarn/bin/prettier")
      (setq prettier-js-args '(
        "--trailing-comma" "all"
        "--bracket-spacing" "false"
      ))
    )
    

2 web-beautify

3 format-all

  • GitHub - lassik/emacs-format-all-the-code: Auto-format source code in many la…
  • 外部の formatter を使うので、自分で用意する。
  • できる範囲で formatter をインスト。私には不要なものを含めて。(debian buster)。
    • prettier(Angular/Vue GraphQL Markdown TypeScript/TSX CSS/Less/SCSS JavaScript/JSON/JSX
    • clang-format (Java + C/C++/Objective-C Protocol Buffers)
    • Rust (rusfmt), Go (gofmt), Haskell (brittany), Python (black)
    • Ruby (rufo), Emacs Lisp (emacs), HTML/XHTML/XML (tidy)
    • SQL (sqlformat), Perl (perltidy), Shell script (shfmt)
    • Assembly (asmfmt(go)), Clojure/ClojureScript (node-cljfmt)
    • YAML (yq -> yq.v2)
  • インストしてないやつ
    • Crystal (crystal tool format), D (dfmt)
    • Elixir (mix format), Elm (elm-format)
    • Kotlin (ktlint), Lua (lua-fmt)
    • OCaml (ocp-indent), Swift (swiftformat)
  • なんにでも対応しているみたいで、素人の私にはこちらが良さそう。

    (use-package format-all :ensure t :defer t
     :bind (:map prog-mode-map
            ("<M-f8>" . format-all-buffer)
    ))
    

4 hydra でメニューに加える

‘C-x C-s’ が手に馴染んでいて、その度に一瞬待たされるのが嫌で、 hydra に登録して、手動で実行するようにした。

(defhydra hyd-dict (:hint nil)
  "dic, spell and formatter"
  ("G" skk-get "get dic(web)" :column "skk")
  ("E" skk-edit-private-jisyo "edit p jisho")
  ("w" lookup-pattern "lookup word" :column "lookup")
  ("r" lookup-region "lookup for region")
  ("W" eww-search-words "eww-search")
  ("s" ispell-word "ispell word" :column "flyspell")
  ("b" flyspell-buffer "ispell buffer")
  ("t" powerthesaurus-lookup-word-at-point "at point" :column "thesaurus")
  ("T" powerthesaurus-lookup-word "word")
  ("d" powerthesaurus-lookup-word-dwim "dwin")
  ("f" format-all-buffer "format-all" :column "formatter")
  ("h" web-beautify-html "beautify H")
  ("c" web-beautify-css "beautify C")
  ; ("p" prettier-js "prettier") ;; not work prettier-mode disable
  ("q" nil "Exit" :exit t :column "Quit")
  ("." nil "cancel" :color blue)
)

ここのメニュに加えるはどうかと思うが、これでしばらく試してみる。

メモしてる時とかは、’fill-paragraph’ とか ‘fill-region’ なのだが、 これさえ使ってなかったことに気付いた。今更だが。

2019年7月9日火曜日

Emacs の ox-hugo で HUGO

ローカルでメモの保存用に使ってみてるサイトジェネレータを、 Pelican から Hugo にしてみた。

150 post を越えて、速度がかなり問題だと思うようになったから。 Pelicanが遅いわけではないので、別ディレクトリに分ければよいのだが、 どうせ分けるなら、別のジェネレータでも試してみるか、ということ。

選んだのは Hugo

速度に関する評価が高いみたいで、 しかも emacs との連携が ox-hugo を使うと便利みたいだから。 (感謝)


hugo の 設定

Hugo 自体の設定は、いっぱい情報があるから省略。というか、細かい設定なんかは、私の理解の外。 html にして表示できれば満足だから。ただ、テーマは、

を試して、Mainroad にしてみた。

emacsでの使い方

ox-hugo をインストしただけで、これ自体の 設定は得にしてない。 こいつを使えば、org-modeで編集したものを、 org-modeの特徴を活かしつつ、 hugo の為に export をしてくれるという。 org-mode(oxとか)が使えていることが前提だが。

基本的な使い方は、公式ドキュメントや先人方の情報のおかげで、なんとかなる。あとは、 hugo用のorgファイルと、org-capture の設定を自分用に用意する。

結局以下のようにして、一応動いているようだ。

解説をちゃんと読めばよいのだが、私には十分かも、と思っている。

hugo用のorgファイル(0730up)

#-*- mode: org -*-
#+CATEGORY: blogger_hugo
#+STARTUP: contents align shrink
#+OPTIONS: AUTHOR:nil
#+HUGO_BASE_DIR: ~/Documents/mup/blogg-hugo
#+HUGO_AUTO_SET_LASTMOD: t
#+HUGO_SECTION: posts

* build [2019-07-11] 追加 
#+BEGIN_SRC shell
cd ~/Documents/mup/blog_hugo
hugo
#+END_SRC

* Posts
** DONE posting test 1              :@hugo:setup:
CLOSED: [2019-07-05 金 10:40]
:PROPERTIES:
:EXPORT_FILE_NAME: 20190705_1st-post
:EXPORT_HUGO_FRONT_MATTER_FORMAT: toml
:EXPORT_HUGO_SECTION: posts
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :archives 2019/07
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :series [debian hugo setup]
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc 2 :num t
:END:


ここは、アブストラクトとして、記事リストに表示される部分。

<!--more-->

これ以降が、本文という位置付けだが、アブストラクト部分も本体に表示されるので、
そのような構成にする必要がある。

exportすると、posts ディレクトリに出力される。
  • HUGO_BASE_DIR で、hugoのディレクトリを指定。
  • HUGO_SECTION の default は ox-hugo の設定や、 orgファイルの先頭部分でも指定できる。 hugo_base_dirに無ければ、作成してくれる。
  • post する時のファイル名は、タイムスタンプと名前でorg-captureで作成。
  • org-mode のタグは、 @ 付きが category、他がtag。
  • :toc 2 は、2レベルの目次
  • :num t で番号付きにできるようだが、私の環境では、記事での設定は、NG. ox-hugo の設定で指定すればOK。

    (setq org-hugo-export-with-section-numbers t)

  • TODO なら ドラフト。DONE にすると公開。

  • list や weblink は普通に使える。

  • 画像ファイルの指定は注意が必要。

    • 同一ディレクトリに画像ファイルがあれば、 ‘static/ox-hugo’ にexport時にコピーしてくれる。

      [[./rimg3576.jpg]]
      file:rimg3576.jpg
      
    • サブディレクトリに画像ファイルを置く場合は、自分でコピーする必要があるようだ。例えば、src=“./imgs/rimg3576.jpg” にするなら、以下。

      [[file:./imgs/rimg3576.jpg]]
      file:./imgs/rimg3576.jpg
      

追記: ひとつのファイルにまとめようとすると、結構多きくなるのに今更気付いた。 で、org-refile のターゲットに新しいファイルを追加することにする。

org-captureの設定(0730up)

公式ドキュメントの方法を使うべきなんだろうが、理解できないので、こんな風になった。

(defun my/generate-post-name ()
  (setq my-org-note--name (read-string "Name: "))
  (setq my-org-note--dtime (format-time-string "%Y%m%d-%H%M"))
  (format "%s_%s.md" my-org-note--dtime my-org-note--name))
;;
...
(setq org-capture-templates  '(
...
...
    ("ph" "hugo new post" entry
      (file+olp "blog_hugo.org" "Posts")
      "** TODO %? \t:@debian:\n:PROPERTIES:\n\
:EXPORT_FILE_NAME: %(my/generate-post-name)\n\
:EXPORT_HUGO_FRONT_MATTER_FORMAT: toml\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :archives %<%Y\/%m>\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :series hugo\n\
:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :toc 2 :num t
:END:\n\n\n\nl<!--more-->\n")
...
 ;; (0730) archives の年月を自動、 del `+`
...
))
...
  • Posts配下に作成
  • 名前だけは入力するようにした。
  • tag や archives なんかはデフォを指定しているだけ。
  • series はhugo側で別途設定が必要みたい。
  • toc をデフォで有にしおく。
  • テーマによって使えなかったり使えたりがある。

一応動いているようだ。
markdown や reStructuredText を直接書いたり、 exportしてからのコピペが不要になるので、かなり楽になると思う。

あとは、使える/使えないを経験しながらでよういだろう。
とりあえず、これで良しとしよう。

2019年7月6日土曜日

コマンドラインツールをふたつ、インストしてみた

コマンドラインのツールをふたつ、インストしてみた。 ネタ元は、 ここ

  1. fdupes 二つのディレクトリを比較して、重複ファイルを表示。

    INSTALL の記述どおりにインストすればよいだけだった。 たまに、こんな機能が欲しい時がある。ただ、 delete オプションは怖いので、基本使わない。

    debian のパッケージにもあった。(1:1.6.1-2 amd64)

    $ fdupes -R ezjnxwin-v0.54beta-2019 ezjnxwin-v0.52beta-2016/
    
    ezjnxwin-v0.54beta-2019/NoMap.jpg
    ezjnxwin-v0.52beta-2016/NoMap.jpg
    
    ezjnxwin-v0.54beta-2019/System.Data.SQLite.DLL
    ezjnxwin-v0.52beta-2016/System.Data.SQLite.DLL
    
    ezjnxwin-v0.54beta-2019/ol3map.html
    ezjnxwin-v0.52beta-2016/ol3map.html
    
  2. pet コマンドラインのスニペット

    fdupes のように、たまにしか使わないヤツは忘れるので、 スニペットにしておきたいということで、インストしてみた。

    既に goenv はインストしてあるので、導入自体は以下で簡単。

    $ go get github.com/knqyf263/pet
    

    どっとbashrc の設定では以下を追加したのだが、 環境によって設定が異なるようで、素人なもので、 直すのに結構時間がかかってしまった。

    function prev() {
      PREV=$(echo `history 2 | head -n1 | sed -E ' s/ [0-9]*  [0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*//'`)
      sh -c "pet new -t `printf %q "$PREV"`"
    }
    # 
    function pet-select() {
      BUFFER=$(pet search --query "$READLINE_LINE")
      READLINE_LINE=$BUFFER
      READLINE_POINT=${#BUFFER}
    }
    bind -x '"\C-x\C-r": pet-select'
    

    本来はリモートでも使えるように、syncさせたりするのだろうが、 私には無縁。
    私が使うのは、以下ぐらい。

    • pet list / pet search :: 登録コマンドのリスト表示
    • pet exec :: fzf で、選択実行
    • prev :: 直前のコマンドを登録
    • pet edit :: 登録コマンドの編集

なんか、使っていけそうな感触。
スニッペト関係では、 以前インストした sniboxがあるのだが、 メモリ食いだし、大袈裟すぎるので、使わなくなって、起動もさせてない。 そもそも目的が違うか。

2019年7月3日水曜日

とある駐車場の車止めポール

ポタリングで、とある駐車場で、止ってしまった。

車止めポール、真っ直ぐのやつの方が少ない、と思った。
遊んでてこうなったのか、車でやったのか。

私の力では、わずかにスプリングが曲るだけ。
スプリングに残留変形が生じるまでとは、なかなかのものだと感心。

2019年6月20日木曜日

滋賀へのライド

最近は、ビワイチのコースはまず走らない。 なんか、つまらないから。

今日は、天ケ瀬ダムから、瀬田川、大石義民の碑、大戸川を遡ってから琵琶湖方面へ、 瀬田の南側をぶらついてみた。

天ケ瀬ダムは何度か通過しているが、時間をとって見学したのは始めて。

瀬田川沿いは、真夏はそれほどでもないのだが、今時分ぐらいが、涼しくてとても気持ちよい。

脇道にそれると、昔からの路と思える場所に、ふと、出会えたりもする。

田園地帯に入れば、短いけどグラベルっぽい路も走れるし、水もきれい。
もう少し暑くなれば、素足で冷却かも。 農薬が気になるが、体温下げれるなら許せるだろう。

今日のお土産は、さくらのハチミツ。 JAのグリーンファーム石山店で、たまたま見付けた。

自転車だと小瓶じゃないと辛いのだが、 桜の時期は短くて出荷量自体が少ないという、 希少品という思いに負けて買ってしまった。

ビワイチだけでなく、琵琶湖周辺にはいろいろ見所ありだと実感している。


が、自転車県みたいな印象があっても、 けっして「インフラが整っている」、「整うようにがんばっている」のではないことを忘れてはいけない。

例えば、この付近は昨年整備されて、歩道も十分に広く、きれいになっている。が、 交差点にゼブラはなく(201905)、あくまで自動車だけを優先する整備をしているようだ。

普通のことで驚くことでもないが、 「ビワイチでけじゃない魅力発見」とかいってても、 車優先社会にかわりはないのだと、何度か感じたライドだった。

2019年6月10日月曜日

コマ図+キューシートみたいなもの、2019春

コマ図+キューシートみたいなもの,を更新してみた。

今年は、国土地理院の 国土数値情報ダウンロードサービス で取得できる施設情報(xmlファイル)から、 Viking のデータファイルへの取り込みを試してみた。

試したのは以下だが、時間ばかり。 パフォーマンスが悪い作業になってしまった。

  • 国・都道府県の機関データ(H25) 14800箇所
  • 市区町村役場(H26) 5774箇所
  • 学校(H25)小学校除く 39689箇所
  • 小学校区(H28) 14668箇所
  • 郵便局(H25) 24526箇所
  • 警察署(H24) 14650箇所
  • 消防署(H24) 5712箇所
  • 鉄道駅(H29) 10327箇所
  • 港湾(H26) 994箇所
  • 漁港(H18) 2931箇所
  • 空港(H29) 100箇所
  • 医療機関(H26) 179046箇所
  • 福祉施設(H27) 38703箇所
  • 都道府県指定文化財(H26)、19255箇所
  • 文化施設(H25) 55921箇所

まあ、施設の座標なので、空白な地域もあるが、 かなりの点数にはなる。

点数が多すぎて、 viking が重くて 使い物にならない。で、viking のデータファイルに含まれるtrackpoint対する距離でインポート時に フィルタさせるようにしてみた。

その結果が以下。まだまだ絞り込みたいかも。

あと、交差点とかのデータがあると嬉しいから、 OSMのデータを、とか思ったりしたが、保留。

まだまだ、試行錯誤で、 TrakPointのnameに、入れてみたり(下図)してみたが、 ピンときてない。データの質がやはり問題なのだろう。

GoogleMap,Yahoo地図との行き来が、ちょと便利になったし、ランドマークの記入も少し楽になったかも、 ということで、今シーズンはこれで良しとしよう。

で、おおまかな流れは以下のようになった。

2019年6月2日日曜日

自転車の夏用長指グローブを更新

長年(3〜4年?)愛用してきた、パールイズミの夏用UV、長指タイプ。 指先に穴が開いてきた。引っ掛けたのではなく、 生地が薄くなってのこと。 昨シーズン、 親指の付け根を針と糸で修繕したのだが、 さすがに寿命だろうと、今年は補修は諦めて購入。

これまでと同モデルだと、 PEARL IZUMI UVフルフィンガーグローブ で、 送料込みで5000円ほど。

で、浮気してみた。 SHIMANO Original ロンググローブ 春夏用

Pearl と Shimano の比較は、 価格帯と時代が異なるので意味ないけど、一応。

  • 縫製はpearlの方が複雑で部品数も多いようだ。 しかも、人差し指まわりに補強があるので、丈夫そう。 こうゆうとこが、価格差なのかも。
  • パットは、shimanoの方が、広範囲をカバーしていて、厚みもある。 今回選んだ理由のメイン。pearlには、手首の中央線上にパッドが無い。 両方とも、各指に分れた部分まで、パッド(補強)がある。
  • pearlは、掌側にメッシュ部分があるが、shimanoには無い。
  • pearlは手首部分をある程度カバーするが、shimanoは短かい。 これが結構気になっていた。夏もジャージは長袖だから。

ライドでの第一印象

90kmほど、ドロップハンドルで使用した印象。

  • わりとタイトなので、着脱が面倒(新品だからかも)。 マジックテープによるカフスアジャスターが着脱に邪魔で イラッとすることがある。
  • 掌側にメッシュが無いためか、汗感が強い。が、 pearl よりグリップ感は良いと思う。パンチングでもするか、と思ったり。
  • パッドの効果は、shimanoの勝ち(へたったpearlとの比較は無意味だけど)。 フラットバーだと、今でもpearlの勝ち(ちょい乗りだったけど)。
  • 堅牢さに、少々不安?かも。

夏用の長指グローブは選択肢が限定されるのだが、 さらに、MTBサポート用というやつがあるかも、 と、ひとつ勉強になった。かも。

そろそろ2ボトルにする時期かな。


一月ほど使ってみた印象

  • 耐久性に少し不安。
    指先がケバだってきた。夏用の生地なんで、そんなものかもしれない。
  • グリップ(ダイレクト)感が低いと感じてしまう。
    掌側のレザー風の生地に伸縮性があるためか、 パッドの厚みの相俟って、ホールド感の不足を感じる。 適材適所で素材を使い分けするような価格帯の商品ではないので、 妥協すべきかも。

2019年5月26日日曜日

自転車で湖南三山、長寿寺

いつもは中山道をなぞるのだが、 県道117をからめながら湖南方面へ。

路面状況も悪くなく、車も少なく、 穏かなツーリングができる。 甲賀や日野へゆく時は、良いルートかもしれない。

で、 長寿寺 、 新緑豊かで、心地良いく、落ち着く。

檜皮葺の本堂が国宝のようだが、 それより、全体の雰囲気がよい。 入山料 500円 は高くはない。

手水にしても、こんな雰囲気。

参道には、 木漏れ日の中で休息できる場所が 数カ所用意されている。

しかも、 参拝後に、受付でお茶とアメを出して頂けた。

ボトルを持って入山しなかったのが残念。 紅葉や桜の季節は人が多くて大変そうだが、 また、立ち寄りたい場所になった。

2019年5月15日水曜日

緯度経度による距離計算に、pythonのnumpyを使ってみた

gpxのログから、 とある緯度経度に最も近い点を求めるのに、 pythonのnumpyを使ってみた。

今迄は、手持ちのPOIしか扱うことがなかったので、 点数が少なく、listの計算で不満は無かった。 しかし、地理院からゲットできる公共施設の住所と座標を扱おうとすると、 5000点(全国で、データによっては5万)を越えるので、 とても遅くなる。 これを解消したかった。

やったことは、 ログの緯度経度を、radianなnp.arrayにして、 対象座標との距離を計算して、結果をarrayに収める。 あとは、argmin()で、最小値のindexを求める。

def calc_dist_array(lad_ar, lod_ar, ck_rlad, ck_rlod):
    """Calc distance."""
    #

    d_x_ar = lad_ar - ck_rlad
    d_y_ar = lod_ar - ck_rlod
    dx_ave = (ck_rlad + lad_ar) / 2.0

    w_2_ar = 1.0 - 0.0066943800230118 * np.sin(dx_ave)**2
    m_m_ar = 6335439.32708317 / np.sqrt(w_2_ar) / w_2_ar
    n_n_ar = 6378137.0 / np.sqrt(w_2_ar)
    t_2_ar = n_n_ar * np.cos(dx_ave) * d_y_ar

    return np.sqrt(m_m_ar**2 * d_x_ar**2 + t_2_ar**2)


np_dist = calc_dist_array(
    np.radians(np.array(gpx_log_latigude)),
    np.radians(np.array(gpx_log_longitude)),
    math.radian(target_rat), math.radian(target_lon))

nearest_index = np_dist.argmin()

これを使って、gpsのログが通過する住所リストを作成してみた。

大阪府高槻市田能スハノ下11
京都府亀岡市安町野々神8
京都府南丹市八木町八木東久保29-1
京都府南丹市園部町小桜町47
兵庫県篠山市福住344-1
兵庫県篠山市日置385-1
兵庫県篠山市北新町41
兵庫県篠山市網掛429
兵庫県篠山市宮田240
兵庫県丹波市柏原町柏原1
兵庫県丹波市氷上町成松甲賀1
兵庫県丹波市柏原町柏原1

リストで処理するよりかなり早くなったが、 5万点になるとさすがに使えそうにない。
もっと良い方法があるかもしれない。

例えば、最小を判定できればよいので、 1degree=94km で処理するとか、 フィルタをかけて、5万点から桁落ちさせるとか、 色々工夫の余地はありそう。
あと、番地以下が不要とか、 公共施設の近所を通過しないログだと役立たずとか。

う、不満だらけだ。

まあ目安程度なら使えるかも。
まあ、よしとしておこう。

2019年5月10日金曜日

「譲り合い」について

車や自転車を運転していて「譲り合い」が発生する際に、 いくつかの状態があるのだと、今更ながら考えてしまった。

  1. 譲りたい、譲ります。

    こうありたい。

  2. 譲って欲しい、譲られたい。

    今は良いけど、さらに年齢を重ねると、ヤバいかも。

  3. 譲れ、譲られるのが当然だ。

    戒めたい。

  4. 譲らないのなら、考えがある。

    絶対、ダメだろう。

自分はどんな状態で車や自転車に乗ってるだろうか。 ケースバイケースというのも、マズそうだ。

更に年齢を重ねても、 素直にブレーキ操作が出来るようにするには、1を心掛けたいと思う。 でないと、意識の外でアクセル側の操作をしてしまうかもしれない。

先日の大津の事故報道を聴いていて、特殊な気分になったのかもしれない。

とある1日、

  • 自転車で2車線道路の左端を走行中、右からライトバンが出てきて併走状態 になった。その車は、左折のためにノーズを自転車前方に被せてきて、左折 させろと迫ってきた。某有名製薬会社の社名が見えた。
  • 横断歩道を青で渡っていたら、右折車が目の前を、ゆっくり、横切ってゆく。 ドライバーは、白髪の老婦人で、右手を上げて、満面の笑顔だった。
  • 全方向一時停止の信号の無い十字路で、自分が自転車歩行者もあり。そこに 阪○○○シーが一時停車もせず、歩行者の前を右折していった。

こんなことは、自転車に乘ってればよくあることで、 感情的になれば、1 でいられなくなる。

が、企業名しょってるのに、と思ってしまう自分が情けない。

いつだったか、日○警○の車が、 信号のない横断歩道で、 前方信号が赤なのに、 待っている小学生をずっと凝視しながら、 徐行で通過していった。 まあ、これはテロリスト対策で、 停止しないように社内で定められているにちがいない。

ああ我、浅ましきかな。
省みれたので、良しとするか。

2019年5月6日月曜日

pythonでicalendarを試してみた(parseだけ)

khal のコマンド作成の スクリプトを作ってはみたが、登録が重複するのはまずいので、 登録済かどうか確認するのに、 icalendar を使ってみた。

khal は ローカルにファイルを保管していてサーバとのやり取りは無いので、 やってみる気になった。しかも、parseだけ出来ればよいので。

#!~/.pyenv/shims/python
"""Read and Check ical data file."""

from __future__ import unicode_literals

import sys
import logging
from pathlib import Path

import logzero
from icalendar import Calendar


def parse_icalfile(f_path, ride_log):
    """Parse icalendar file."""
    cal_fobj = open(f_path, 'rb')
    k_calen = Calendar.from_ical(cal_fobj.read())
    cal_fobj.close()
    for cal_ev in k_calen.walk():
        if cal_ev.name == 'VEVENT':
            start_year = cal_ev.get('dtstart').dt.strftime("%Y")
            ride_log[start_year].append(k_calen)

    return ride_log


def sel_event_list(ride_log, t_day):
    """Select events by target date character."""
    event_list = []
    for ical_obj in ride_log[t_day[0:4]]:
        for cal_ev in ical_obj.walk():
            if cal_ev.name == 'VEVENT':
                summary = cal_ev.get('summary', default='None')
                descrip = cal_ev.get('description', default='None')
                start_dt = cal_ev.get('dtstart').dt
                end_dt = cal_ev.get('dtend').dt
                event_item = "{0:s}{1:s}:{2:s}({3:s})".format(
                    start_dt.strftime("%Y%m%d%H%M"),
                    end_dt.strftime("%m%d%H%M"), summary, descrip[0:20]
                )
                event_list.append(event_item)

    logzero.logger.info("- All entry {0:s}".format(t_day[0:4]))
    for s_str in sorted(event_list):
        logzero.logger.info(s_str)

    c_event = [e for e in sorted(event_list) if e[0:len(t_day)] == t_day]

    return sorted(c_event)


def main():
    """Do main prcess."""
    #
    khal_dir = Path.home() / "Documents/ownCloud/caldav/bikes/"

    ride_log = {
        "2016": [], "2017": [], "2018": [], "2019": [], "2020": []
    }

    for f_path in khal_dir.glob('*'):
        ride_log = parse_icalfile(f_path, ride_log)

    t_date = '20190412'

    target_ev_list = sel_event_list(ride_log, t_date)

    if target_ev_list == []:
        logzero.logger.info("- No entry on {0:s}".format(t_date))
    else:
        logzero.logger.info("- target {0:s}".format(t_date))
        for mes_str in target_ev_list:
            logzero.logger.info("  {0:s}".format(mes_str))


if __name__ == "__main__":

    LOG_FORMAT = "%(color)s[%(module)s:%(lineno)d]%(end_color)s %(message)s"
    FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
    logzero.setup_default_logger(formatter=FORMATTER)
    logzero.loglevel(logging.INFO)
    logzero.logfile("./_logs/log.log", maxBytes=3e5, backupCount=3)

    main()
    sys.exit()
#

まずまずなのだが、 登録済確認をスクリプト内で出来れば良いのだが、 私には無理なので、目視確認とした。

gpxのログを読み込んで、その概要を掃き出すスクリプトを改造して、 khalコマンドとicalendarの作成と併せて、確認させてみた結果の例が以下。

# Check 015: 2019-04-26 09.10.03 Day.gpx
- time (2019-04-26 09:10:03 JST) - (2019-04-26 16:30:22 JST)
- trip 101.0km(382 + (stop 58)min) ave. 15.9km/hr u/d(495.9/551.6)
- farthest 32.9km SE

    $ khal new -a bikes 20190426 09:10 440m ride 101.0k SE32k :: 奈良県天理市

- Bike event 20190426
  20190426091004261630:ride 101.0k SE32k(奈良県天理市 by gpl2cal.py)

# Check 016: 2019-05-03 17.48.26 Day.gpx
- time (2019-05-03 07:53:35 JST) - (2019-05-03 17:47:44 JST)
- trip 147.6km(493 + (stop 64)min) ave. 18.0km/hr u/d(739.2/693.1)
- farthest 53.5km EE

    $ khal new -a bikes 20190503 07:53 557m ride 147.6k EE53k :: 滋賀県東近江市

- Bike event 20190503
  None

コンソール上のコピペで作業ができるので良しとする。

2019年4月27日土曜日

Pythonで第三金曜日とか求めてみた

Pythonで第三火曜日とかを求めてみた。 単純に、ゴミ出し日を、 khal で登録してみたかったから。

いくつか見付けることができたが、 calendarを使う方法と、 dateutilを使う方法を試してみた。 出発点は、 ここ だったかな。

calendar を使う

ゴミ出しは、月毎なので、こちらの方が感覚に合うように思う。

#!~/.pyenv/shims/python
"""Calendat module test."""

import sys
import logging

from calendar import Calendar, TextCalendar

import logzero

LOG_FORMAT = "%(color)s[%(module)s.%(funcName)s:%(lineno)3d]%(end_color)s %(message)s"
FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
logzero.setup_default_logger(formatter=FORMATTER)
logzero.logfile("./log000.log", maxBytes=3e5, backupCount=3)
logzero.loglevel(logging.DEBUG)

def match_weekday(c_year, c_month, c_wday, c_oweek):
    """Calc date of n-th weekday."""
    # c_year, c_month = 2019, 5
    # c_wday = 5   # Monday is Zero
    # c_oweek = 2  # 1st weeek is Zero

    # 指定されて曜日だけのリスト作成
    weday_list = Calendar(firstweekday=0).monthdayscalendar(c_year, c_month)
    sel_wekday = [x[c_wday] for x in weday_list if x[c_wday] != 0]

    # 指定された週の日付を返す
    try:
        match_date = sel_wekday[c_oweek]
    except IndexError:
        match_date = -1

    return match_date


def main():
    """Do main."""
    #

    wday_char = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    week_char = ["1st", "2nd", "3rd", "4th", "5th"]

    r_year, r_month = 2019, 5
    r_weday = 4  # Zero is Monday
    r_oweek = 2  # 1st weekday is Zero

    # 指定された年、月のカレンダーの表示
    tcalendar = TextCalendar(firstweekday=r_weday)
    print(tcalendar.formatmonth(r_year, r_month))

    match_day = match_weekday(r_year, r_month, r_weday, r_oweek)

    logzero.logger.info(
        "\n* {0:s} {1:s}({2:02d}/{3:02d}) 不燃ゴミ".format(
            week_char[r_oweek], wday_char[r_weday], r_month, match_day
        )
    )

    logzero.logger.info(
        "\n* khal new -a garbage {0:4d}{1:02d}{2:02d} 不燃ゴミ".format(
            r_year, r_month, match_day
        )
    )

    sys.exit()


if __name__ == "__main__":
    main()
    sys.exit()
#

   $ python t15_calendar.py
         May 2019
   Fr Sa Su Mo Tu We Th
                   1  2
    3  4  5  6  7  8  9
   10 11 12 13 14 15 16
   17 18 19 20 21 22 23
   24 25 26 27 28 29 30
   31

   [t15_calendar.main: 88]
       * 3rd Fri(05/17) 不燃ゴミ
   [t15_calendar.main: 94]
       * khal new -a garbage 20190517 不燃ゴミ

dateutil を使う

ゴミ収集日なので、4週めまででよい。
もっと複雑なことをやるためのツールという印象。

datetimeなので、該当日が休日かどうかも判定させてみた。 休日の判定は、 jpholiday を使ってみた。

#!~/.pyenv/shims/python
"""dateutil and jpholiday module test."""

import sys
import logging
import datetime
from calendar import TextCalendar

import logzero
import jpholiday
from dateutil.rrule import MONTHLY, rrule

LOG_FORMAT = "%(color)s[%(module)s.%(funcName)s:%(lineno)3d]%(end_color)s %(message)s"
FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
logzero.setup_default_logger(formatter=FORMATTER)
logzero.logfile("./log000.log", maxBytes=3e5, backupCount=3)
logzero.loglevel(logging.DEBUG)


def match_weekday2(c_year, c_month, c_wday, c_oweek):
    """Calc date of n-th weekday."""
    # c_year, c_month = 2019, 5
    # c_wday = 5   # Monday is Zero
    # c_oweek = 2  # 1st weeek is 1

    # 指定されて年、月の開始日
    dt_stday = datetime.date(c_year, c_month, 1)

    # 指定されて年、月の1日から4つめまでの指定曜日リストから選択
    try:
        match_date = rrule(
            freq=MONTHLY, dtstart=dt_stday, byweekday=c_wday, count=4
        )[c_oweek]
    except IndexError:
        # 該当がなければ、負
        match_date = -1

    return match_date


def main():
    """Doing a read viking file for make class."""
    #

    r_year, r_month = 2019, 5
    r_weday = 4  # Zero is Monday
    r_oweek = 0  # 1st weekday is Zero

    tcalendar = TextCalendar(firstweekday=0)
    print(tcalendar.formatmonth(r_year, r_month))

    match_day = match_weekday2(r_year, r_month, r_weday, r_oweek)
    if rr_day != -1:
        mes_str = match_day.strftime("\n* %m-%d %a 不燃ゴミ")
        if jpholiday.is_holiday_name(match_day.date()):
            # 休日だったら、追加
            mes_str += ": {0:s}".format(
                jpholiday.is_holiday_name(match_day.date()))
        logzero.logger.info(mes_str)


if __name__ == "__main__":
    main()
    sys.exit()
#


   $ python t15_dateutil.py
         May 2019
   Mo Tu We Th Fr Sa Su
          1  2  3  4  5
    6  7  8  9 10 11 12
   13 14 15 16 17 18 19
   20 21 22 23 24 25 26
   27 28 29 30 31

   [t15_dateutil.main:114]
       * 05-03 Fri 不燃ゴミ: 憲法記念日

これを、今月と来月について、 まとめて表示させたのが以下。


$ python garbage_date.py 
  
     2019-05 (current month)
    
     !!  check
     khal list -a pubs 20190501 30d
    
     khal new -a pubs 20190507 空缶、危険、有害ゴミ :: garbage
     khal new -a pubs 20190514 古紙、布, ペットボトル :: garbage
     khal new -a pubs 20190521 空瓶、ガラス :: garbage
     khal new -a pubs 20190528 燃えないゴミ :: garbage
    
     2019-06 (Next month)
    
     khal list -a pubs 20190601 29d
    
     khal new -a pubs 20190604 空缶、危険、有害ゴミ :: garbage
     khal new -a pubs 20190611 古紙、布, ペットボトル :: garbage
     khal new -a pubs 20190618 空瓶、ガラス :: garbage
     khal new -a pubs 20190625 燃えないゴミ :: garbage

ターミナル上のコピペで作業できるようになった。よしとしよう。

2019年4月25日木曜日

Emacsのrst-modeの設定見直し

markupでのメモ作業は、orgがメインだが、 たまにmarkdownと reStructuredText( rst )を直接使う。sphinxとPelicanを使ってるから。

emacsの設定方法は、 orgやmarkdownについては比較的容易に見付けることができるが、 rst の方はなんとも、 という状況みたい。コピペなんで。

これまでは、標準の rst-modeyasnippetflycheck (rstでは、sphinx-build) を 併せて使ってきている。

ちなみに、rst-mode の使っている機能は、

  • headerの設定
  • tocリスト (imenuで十分だったりする)

ぐらいで特に必須ではないように思う。 listさえ使ってない状況。 当然、効率は著しく悪い。 使い方は、 ネットで探すより rst.el に含まれる英語のドキュメントの方が 私には適切に思えたのだが。

一番不満なのが、outlineが使えないこと。 outlineは、一応、outline-minor-mode を使っているが、 headerを上手に認識してくれず、サポート外のように思える。

そこで今回 move-text を入れてみた。 line-up/down region-up/downが使えれば、 yank,paste とかとの併用で、それなりに改善されるかもと考えたから。

    (use-package rst :ensure nil :defer t
     :bind( :map rst-mode-map
            ("C-c r" . rst-preview-by-eww)
            ("C-M-<down>" . move-text-down)
            ("C-M-<up>" . move-text-up)
          )
     :mode
      ("\\.rst\\'"  . rst-mode)
      ("\\.rest\\'" . rst-mode)
     :config
      (add-hook 'rst-adjust-hook 'rst-toc-update)
      (setq indent-tabs-mode nil)
      (setq electric-indent-mode t)
      (setq electric-quote-mode nil)
      ;
      (defun rst-preview-by-eww ()
        (interactive)
        (message (buffer-file-name))
        (call-process "pandoc" nil nil nil
                      (buffer-file-name)
                      "-o"
                      "/tmp/rst.html")
        (let ((buf (current-buffer)))
          (eww-open-file "/tmp/rst.html")
          (switch-to-buffer buf)
          (pop-to-buffer "*eww*")))
     ;
    (use-package move-text :ensure t)
    )

結果として、随分ましになったように思う。 lineでもregionでも上下移動が可能になる。 で、慣れてくれば当然、 promote/demote が欲くなるが.....

rst.el 自体はメンテされているようで、 Debian(buster)のrst.elはemacs26.1までだが、 公式ページのヤツは26.2のようだ。 エキスパートの方達はどう使っているのか不思議。

なお、pandocを使ってewwでpreviewしている(どこかのコピペ)が、 これは、flycheckをオフにして、previewでチェックする、 という使い方になっている。まあ、短かい文章だし、 見た目の確認の必要性はそれほど感じなていない。

riv.vimの方が高機能みたいだが重い。

ちょっとだけ前進したかも。まだまだ先は長そう。 しかし、達人はどう使っているのだろう。

2019年4月19日金曜日

今年の桜も終り

sakura

今年の桜も終り。

お団子は無かったけど、花鎮祭(はなしずめのまつり)に出会えたのよかった。 たまたま遭遇したイベント(亀岡の出雲大神宮)。 ちょうど神楽?をやっていた。

肩に乗ったり、掛け合いもジョーク混りで面白かった。 チャリなんで長居できず残念な気分になった。 後で知ったのだけど、伊勢大神楽らしい。

「出雲風流花踊り」というのがメインらしいが チャリなんで、時間がなかった。雨乞いと豊作祈願祈願らしい。あってるかな。

ぶらぶらしていて、何かに出会えるのポタリンの楽しみ。 梅雨の前に、もっと出掛けたいと思った一日。

2019年4月15日月曜日

Emacs の org-mode で export 先を指定

これまで、org-modeからexportする場合、 ディレクトリとかファイル名は指定できないと思い込んでいた。 で、コピペを多用していたが、なんのことはない。 プリアンブルで指定すれば良いだけだった( これだから素人は困る)。

#+EXPORT_FILE_NAME:  ~/work/temp.md

ここで知った。

サブツリーでoverwriteできると記載されている。 私の環境ではダメか、と思ったが、export時に c-s でexport対象をsubtree にすればOKだった。 org-narrow-to-subtree で作業すれば、なんとなく幸せかも。

subtree内にPROPERTIESのブロックが無いのに、subtreeをexportしようとすると、 ファイルバッファのデフォルト?が使われて上書きされたりするので注意が必要。 PROPERTIESブロックにカーソルを置いてexportする癖をつけないと。

うまく設定できれば、静的サイトジェネレータ配下への移動が簡素化できる。
mkdocsに挑戦してみるかも。

2019年4月5日金曜日

Emacsのpython(elpy)関係を見直し(201912up)

今回は、python関係を見直してみた。 あくまで初心者用なので、projectとかtestとかは考えてない。 補完と文法チェックが出来ればよし。

環境は、debian(buster)で、pyenvを使って3.7。 virturalenvは使わず、globalにしている。 モジュールは、pipでインスト。

emacsは26.1で、use-package + ivy + company な環境。
company-jedi は使ってない。

基本はいつもどおり、コピペ。

(201912)pyvenv, jedi-core

pipenv  から  require  されているので、pyenv だけ有効にした。(210912)

  (use-package pyvenv :ensure t)

これまで pyenv-mode を使ってたが、 elpy が pyvenv を使っているので、 今回、 pyvenv にした。

jediは、elpy-module-companyがあるので、jedi-core を インストすれば良いようだ。 elpy-module-company and company-jedi are kind of redondant( https://github.com/jorgenschaefer/elpy/issues/1397)

下の設定は無効化。

   (use-package pyvenv :ensure t
    :mode ("\\.py\\'" . pyvenv-mode)
    :interpreter ("python" . pyvenv-mode)
    :after projectile
    :config
     (use-package jedi-core :ensure t
      :config
       (add-hook 'python-mode-hook 'jedi:setup)
       (setq jedi:complete-on-dot t)
       (setq jedi:use-shortcuts nil)
    )
   )

pipenv, jedi-core(201906)

pipenv を使ってみようと、 変更してみた。 pipenv 自体の使い方は、以下など参考にしてやってみた。

これまでは、home ディレクトリ全体を、pyenv で 3.7 にしてあるだけで、 作業フォルダ毎の仮想環境は使っていなかった。

まだ、一つの作業でしか試してないが、 なんとか使えているように思う。 のだが、emacsの反応が少し遅くなった?ように感じる。

projectile は一応動いているかも、という状態で意識的に使ってないない。 まあ、プロジェクトなんて僅かだから。

  (use-package pipenv :ensure t
    :diminish (pipenv-mode . "penv")
    :hook (python-mode . pipenv-mode)
    :init
    (setq pipenv-with-projectile nil)  ;; Disable Projectile integration
    ;; まだ使い熟せてないし、理解もできてないから。
    ;; (setq
    ;;  pipenv-projectile-after-switch-function
    ;;  #'pipenv-projectile-after-switch-extended)
    :config
    (setq pipenv-with-flycheck nil)
    ;; Use the pipenv env. when searching for Flycheck executables.
    )
    ;; [updata 201912]
    ;;
    ;; (use-package pipenv :ensure t
    ;; :hook (python-mode . pipenv-mode)
    ;; :custom
    ;;  (pipenv-projectile-after-switch-function #'pipenv-projectile-after-switch-extended)
    ;; )
    ;; C-c C-p a   pipenv-activate
    ;; C-c C-p d   pipenv-deactivate
    ;; C-c C-p s   pipenv-shell

   (use-package jedi-core :ensure t
    :config
     (add-hook 'python-mode-hook 'jedi:setup)
     (setq jedi:complete-on-dot t)
     (setq jedi:use-shortcuts nil) ; M-. and M-,
   )

pipenv のメモ

ディレクトリ作成、移動、インスト

  $ mkdir hoge
  $ cd hoge

  # 仮想環境の構築
  # $ pipenv install
  $ pipenv --python 3.7,3
  # $ pipenv --python 2.7.14  Python 2.7.14 を使う

  # PipfileとPipfile.lockが作成される。
  #  + Pipfile => 設定ファイル
  #  + Pipfile.lock => インストールしたライブラリ情報

Pipenvシェルを有効化、パッケージ管理

  $ pipenv shell
  $ pipenv install pylint
  $ pipenv install --dev epc
  # pipenv install --dev XXXX   開発時しか使わないなら
  $ exit  ::停止

  # emacs で使うやつ。
  #   epc, jedi, autopep8, pylint, yapf, isort, black
  #   black は --pre が必要だった
  # Pipfile に記述して、
  #   $ pipenv update
  # で全パッケージをインスト、更新できる

python-mode

elpyを使うには python-mode が事前に有効になっている必要がある。 折り畳みは、buildinの outline-minor-mode を使っている。

Debian のパッケージでインストされる /usr/share/emacs/26.1/lisp/progmodes/python.el.gz を使うようにした。 (201908)

   ;; [add 201912]
   (add-to-list 'interpreter-mode-alist '("python3" . python-mode))
   ;;
   (use-package python-mode :ensure nil
     :mode ("\\.py\\'" . python-mode)
     :interpreter ("python" . python-mode)
     ;; :after pyvenv-mode
     :config
     (python-mode)  ;; (201912)
     (setq python-indent-guess-indent-offset-verbose nil)  ;; (201912)
     ;; Non-nil means to emit a warning when indentation guessing fails.
     ;;
     (setq electric-indent-local-mode nil)
     (setq py-smart-indentation t)  ;; new in ver 6.2.4
     ;;
     (setq electric-indent-local-mode -1)
     ;; (setq indent-tabs-mode nil)  ;; original nil  (201912)
     ;; (setq py-indent-tabs-mode nil)  ;; original nil
     ;; (setq python-indent-offset 4)  ;; default 4
     ;;

     ;; (setq python-check-command "~/.pyenv/shims/pylint")  ;; 重複、コメントアウト
     (setq python-shell-interpreter "python")  ;; (201912)
     (setq python-shell-completion-native-disabled-interpreters '("python"))  ;; (201912)
     ;; (setq python-shell-interpreter-args "-i")  ;; original "-i"
     ;;
     (flymake-mode nil)  ;; (201912)
     (outline-minor-mode t)

     (setq python-check-command "~/.pyenv/shims/pylint")  ;; (201912)
     ;;
     ;; (201912) move to eldoc config.
     ;; (eldoc-mode t)
     ;; (setq eldoc-echo-area-use-multiline-p t)
     ;; (setq eldoc-idle-delay 3)
     ;; (setq eldoc-minor-mode-string nil)
     ;; (setq python-fill-docstring-style 'pep-257) ;; original pep-257
    )

elpy(includ company)

基本の設定に、上記と、gtags があれば、初心者の私には十分だと思うが、 elpy を入れると編集が少し楽になると感じている。

   (use-package find-file-in-project :ensure t
    :after projectile
    )
   ;;

   (use-package elpy :ensure t
    :diminish (elpy-mode . "elpy")
    :after python-mode
    :hook (python-mode . elpy-enable)
    ;; ここを elpy-mode にすると、python-modeになってないと怒られる。
    ;:init
    ;(package-initialize) ;; 無くても大丈夫そう
    :config
    (elpy-mode)
    ;for emacs26.1 is a new flymake.
    (when (require 'flycheck nil t)
     (setq elpy-modules (delq 'elpy-module-flymake elpy-modules))
     (add-hook 'elpy-mode-hook 'flycheck-mode))
    (setq elpy-syntax-check-command "pylint")
    ; flake8 がうまく動いてくれないから。きっとversionが附合してない。
    ; 初心者にはpylintよりflake8が向いていると、どこかで読んだ記憶がある。
    (delete 'elpy-module-highlight-indentation elpy-modules)
    ;; elpy は https://github.com/antonj/Highlight-Indentation-for-Emacs
    ;; を使ってる。

    ;; https://www.reddit.com/r/emacs/comments/8i4x57/is_it_possible_to_disable_elpy_minibuffer_output/
    ;; Original value was when-shell-not-visible  (201912)
    (setq elpy-shell-echo-output nil)

    ;; https://github.com/jorgenschaefer/elpy/issues/1416   (201912)
    (setq elpy-eldoc-show-current-function nil)

    (outline-minor-mode t)  ;; (201912)
    (flymake-mode nil)  ;; (201912) 記入漏れ
    )

elpy-config の結果は以下。

    Elpy Configuration

    Virtualenv........: None
    RPC Python........: 3.7.3 (/home/hogehoge/.pyenv/shims/python)
    Interactive Python: python (/home/hogehoge/.pyenv/shims/python)
    Emacs.............: 26.1
    Elpy..............: 1.18.0
    Jedi..............: 0.15.1
    Rope..............: 0.14.0
    Autopep8..........: 1.4.4
    Yapf..............: 0.29.0
    Black.............: 19.3b0
    Syntax checker....: pylint (/home/hogehoge/.pyenv/shims/pylint)
  • elpy-module-company が上手く使えているのかは不明。それなりに使えていると思う。

  • shell buffer、TEST、Djangoは使ってない。

  • C-c C-r r (elpy-refactor) は rope を使うらしいが、理解できてない。

    リファクタリング (refactoring) とは、コンピュータプログラミングにお いて、プログラムの外部から見た動作を変えずにソースコードの内部構造を 整理することである。wikipedia

  • flymake は flychek のキーバインドを使う。

    elpyのキーバインドは、flycheckに対応していないようだ。

  • カーソル移動は普通。

    カーソルのブロック単位での移動は c-up/down(at the line head), right/left

  • 対象領域の移動させるのは M-up/down (elpy-nav-move-line-or-region-up/down)

    インデントは M-left/right (elpy-nav-indent-shift-left/right)

  • searchは、 counsel-git-grepdeadgrep を主に使うので、elpyの機能は使ってない?

    • c-c c-f (elpy-find-file: Find a file in the current project)
    • C-c C-s (elpy-rgrep-symbol)
    • M-TAB (elpy-company-backend)
  • naviは、 counsel-gtags を使ってるので、elpyの機能はほとんど使ってない。

    • M-. / M-* (elpy-goto-definition) (pop-tag-mark)
    • C-x 4 M-. (elpy-goto-definition-other-window)
    • C-c C-o (elpy-occur-definitions) imenu-list より見易い。
  • C-c C-d (elpy-doc) try and find the documentation for that object

  • C-c C-r f (elpy-format-code)

  • C-c C-r i (elpy-importmagic-fixup) は使えてない。

  • C-c C-e (elpy-multiedit-python-symbol-at-point)

    うまく動かない。occur を使えばよさそう。

importmagic, py-isort

import関係は、このふたつ。 importmagic は便利そうなんだが使えてない。 結局、 py-isort を叩いている。

   ;;  止め。リアルタイムで動くのは、遅くなるから。(201912)
   ;;(use-package importmagic :ensure t
   ;; :defer t
   ;; :diminish importmagic-mode
   ;; :after python-mode
   ;; :config
   ;; (add-hook 'python-mode-hook 'importmagic-mode))

   (use-package py-isort :ensure t
    :defer t
    :after python-mode
   )

highlight-indent-guides(201908up)

インデントガイドは、highlight-indent-guidesを使っている。 インデントガイドは必要だ。
elpy で使ってるやつにすればよかったかもと思ったが、 他でも使うと思うので、汎用性のあるやつとして選んだのだと思う。

(use-package highlight-indent-guides :ensure t
 :diminish highlight-indent-guides-mode
 :hook
  (prog-mode . highlight-indent-guides-mode)
  (rst-mode . highlight-indent-guides-mode)
 :config
  (setq highlight-indent-guides-method 'column)  ;; fill,column,character
  (setq highlight-indent-guides-auto-enabled t)  ;; automatically calculate faces.
)

まだ使えてないものが多いのだが、 一応、使えているような気になれてるので、 よし、としておこう。

Emacs の lsp の設定、なう(202310)

前回さらしてから、さらに1年。そう、3年めになる。 が、今回は一段と自信がない。 環境は、 Debian GNU/Linux 12 (bookworm) + emacs(29.1)。consult + company。 embark は未だに使ってない。 用途は、メモ と ...