トップ 最新 追記   RSS 1.0 FEED  

Journal InTime


2017-02-12 (Sun) [長年日記]

_ Textbringer 0.1.7

Textbringer 0.1.7をリリースした。変更点は、

  • EditorConfigのサポート。
  • CONFIG[:ambiguos_east_asian_width]を追加。 詳細はREADME参照。
  • Cモードの追加。
  • *Completions*バッファの追加。
  • 複数文字コマンドをエコーエリアに表示。

久々に以下のように長い正規表現を書いた。

TOKEN_REGEXP = /\G(?:
(?<preprocessing_directive>
  ^[ \t\f\v]*(?:\#|%:).*(?:\\\n.*)*[^\\]\n
) |
(?<comment>
  (?<multiline_comment> \/\* (?> (?:.|\n)*? \*\/ ) ) |
  (?<singleline_comment> \/\/ .*(?:\\\n.*)*(?<!\\)\n )
) |
(?<partial_comment>
  (?<multiline_comment> \/\* (?:.|\n)* ) |
  (?<singleline_comment> \/\/ .*? \\\n (?:.|\n)* )
) |
(?<keyword>
  (?:
    auto | break | case | char | const | continue | default | double | do |
    else | enum | extern | float | for | goto | if | inline | int | long |
    register | restrict | return | short | signed | sizeof | static | struct |
    switch | typedef | union | unsigned | void | volatile | while | _Bool |
    _Complex | _Imaginary
  ) \b
) |
(?<constant>
  (?<floating_constant>
    (?<decimal_floating_constant>
      (?<fractional_constant>
        (?<digit_sequence> [0-9]+ )? \. \g<digit_sequence> |
        \g<digit_sequence> \. )
          (?<exponent_part> [eE] [+\-]? \g<digit_sequence> )?
          (?<floating_suffix> [flFL] )?
    ) |
    (?<hexadecimal_floating_constant>
      (?<hexadecimal_prefix> 0x | 0X )
          (?<hexadecimal_fractional_constant>
            (?<hexadecimal_digit_sequence> [0-9a-fA-F]+ )? \.
                \g<hexadecimal_digit_sequence> |
            \g<hexadecimal_digit_sequence> \. )
          (?<binary_exponent_part> [pP] [+\-]? \g<digit_sequence> )
          \g<floating_suffix>? |
      \g<hexadecimal_prefix> \g<hexadecimal_digit_sequence>
          \g<binary_exponent_part> \g<floating_suffix>?
    )
  ) |
  (?<integer_constant>
    (?<decimal_constant> [1-9][0-9]* )
    (?<integer_suffix>
      (?<unsigned_suffix> [uU] ) (?<long_suffix> [lL] )?
      \g<unsigned_suffix> (?<long_long_suffix> ll | LL )?
      \g<long_suffix> \g<unsigned_suffix>?
      \g<long_long_suffix> \g<unsigned_suffix>?
    )? |
    (?<hexadecimal_constant>
      \g<hexadecimal_prefix> \g<hexadecimal_digit_sequence> )
          \g<integer_suffix>? |
    (?<octal_constant> 0 (?<octal_digit> [0-7] )* )
        \g<integer_suffix>?
  ) |
  (?<character_constant>
    ' (?<c_char_sequence>
        (?<c_char>
          [^'\\\r\n] |
          (?<escape_sequence>
            (?<simple_escape_sequence> \\ ['"?\\abfnrtv] ) |
            (?<octal_escape_sequence> \\ \g<octal_digit>{1,3} ) |
            (?<hexadecimal_escape_sequence>
              \\x \g<hexadecimal_digit_sequence> ) |
            (?<universal_character_name>
              \\u[0-9a-fA-F]{4} |
              \\U[0-9a-fA-F]{8} )
          )
        )+
      ) ' |
    L' \g<c_char_sequence> '
  )
) |
(?<string_literal>
  " (?<s_char_sequence>
      (?<s_char> [^"\\\r\n] | \g<escape_sequence> )+ ) " |
  L" \g<s_char_sequence>? "
) |
(?<identifier>
  (?<identifier_nondigit>
    [_a-zA-Z] |
    \g<universal_character_name> )
        (?: \g<identifier_nondigit> | [0-9] )*
) |
(?<punctuator>
  \[   |   \]   |   \(   |   \)   |   \{   |   \}   |
  \.\.\.   |   \.   |
  \+\+   |   \+=   |   \+   |
  ->   |   --   |   -=   |   -   |
  \*=   |   \*   |
  \/=   |   \/   |
  &&   |   &=   |   &   |
  \|\|   |   \|=   |   \|   |
  !=   |   !   |
  ~   |
  ==   |   =   |
  \^=   |   \^   |
  <:   |   <%   |   <<=   |   <<   |   <=   |   <   |
  >>=   |   >>   |   >=   |   >   |
  \?   |   ;   |
  :>   |   :   |
  ,   |
  \#\#   |   \#   |
  %>   |   %:%:   |   %:   |   %=   |   %
) |
(?<space>
  \s+
) |
(?<unknown>.)
    )/x

田中哲スペシャルのおかげでC99のBNFを書き写すだけだと思ったのも束の間、左再帰を避けたり、最左最長マッチに合わせて順番を入れ替えるのが結構大儀であった。

インデントの設定項目は(使ったことのない)xyzzyを参考に以下のようなものを用意した。

CONFIG[:c_indent_level] = 4
CONFIG[:c_indent_tabs_mode] = true
CONFIG[:c_continued_statement_offset] = 4
CONFIG[:c_case_label_offset] = -4
CONFIG[:c_label_offset] = -2

以下のように~/.textbringer.rbに設定するとRubyのソースとだいたい同じスタイルになるはず(バッファローカルの設定はindent_levelとindent_tabs_modeはc_が付かないので注意)。

add_hook :c_mode_hook, -> {
  buf = Buffer.current
  if buf.file_name &&
      File.dirname(buf.file_name).end_with?("/ruby")
    buf[:indent_level] = 4
    buf[:tab_width] = 8
    buf[:indent_tabs_mode] = true
    buf[:c_continued_statement_offset] = 4
    buf[:c_case_label_offset] = -2
    buf[:c_label_offset] = -2
  end
}

K&Rスタイルに対応してないのは仕様である。

_ ストームブリンガー

ストームブリンガー 永遠の戦士エルリック

新訳版で読み進めていたがようやく第4巻の『ストームブリンガー』まで読了した。

第3巻所収の『薔薇の復讐』以外は旧訳で読んでいるはずだったが、記憶以上に呪われている感じだったので、Textbringerを使う時はバックアップに気を付けようと思う。

Tags:

2017-02-19 (Sun) [長年日記]

_ Textbringer 0.1.8

Textbringer 0.1.8をリリースした。

0.1.7からの変更点:

  • シンタックスハイライトのサポート
  • grep, gsub, enlarge_windowコマンドの追加
  • CRをLFに変換しないよう修正。

asciicastは8色(正確にはA_BOLDを使った暗黙の色指定を合わせて16色)モードだが、256色の端末にも 対応していて以下のようにRGB値を指定するとカラーパレットから一番近い色を選択する。

# ~/.textbringer.rb
if Window.colors == 256
  Face.define :mode_line, foreground: "#ffffff", background: "#75507b"
  Face.define :link, foreground: "#8ae234"
  Face.define :comment, foreground: "#c4a000"
  Face.define :preprocessing_directive, foreground: "#4e9a06"
  Face.define :keyword, foreground: "#af87af", bold: true
  Face.define :string, foreground: "#729fcf"
end

デフォルトの前景色・背景色は以下のように変更できるが、このあたりの設定方法は変えるかも。

Window.set_default_colors("#ffffff", "#262626")

Curses.init_colorを使えばより正確な色表現ができるはずだが、tmuxとかだとCurses.can_change_color?が falseを返すのでそこまで頑張っていない。