0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Editorを作った気になってみよう

0
Posted at

Emacs使いって言ってたころはもうとうの昔になってしまい、今やエディタとはなんだろうという哲学に囚われてしまった、のどかはです

エディタおもろい

エディタって色々ありますよね

  • Emacs
  • Vim
  • nano
  • PHPStorm
  • VSCode
  • メモ帳

きっとこれもエディタなんだが!超有名なんだが!?って突っ込みがくるかも知れませんが

取り敢えずで上記のエディタを上げました

さて、上記のエディタを自分で作ろうとすると大変ですが

エディト(編集する)という役割を知るためにはもっと簡単なコードで確かめられます

Cってやつで経験する

プログラム本体を示します

#include <stdio.h>
#ifndef SIZE_ALLOCATE
#define SIZE_ALLOCATE 2048
#endif

int main(void){
  char *s = malloc(sizeof(char*) * SIZE_ALLOCATE);
  scanf("%s", s);
  printf("%s", s);
  return 0;
}

これを

gcc foo.c -o foo
./foo // 文字列を入力すると返ってくる

となりました

では次にライブラリとCの関数系統をラップして編集っぽさを出します

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include <string.h>
#include <locale.h>
#ifndef SIZE_ALLOCATE
#define SIZE_ALLOCATE 2048
#endif

int main(void){
  setlocale(LC_ALL, "");
  int h,w;
  echo();
  cbreak();
  initscr();
  getmaxyx(stdscr, h, w);
  char *s = malloc(sizeof(char*) * SIZE_ALLOCATE),
       *buffer = malloc(sizeof(char*) * SIZE_ALLOCATE * 100),
       c;
  do {
    refresh();
    move(0, 0);
    printw("start memory_size: %d, w: %d, h: %d\n", SIZE_ALLOCATE, w, h);
    move(h-1, 0);
    printw("echo > ");
    scanw("%s", s);
    erase();
    strcat(buffer, s);
    move(1, 0);
    addstr(buffer);
  }  while(0 != strcmp(s, "exit"));
  endwin();
  return 0;
}

以下でコンパイル

gcc edit.c -o edit -DSIZE_ALLOCATE=1024 $(pkg-config --libs --cflags ncursesw)

文字列追加してエンターしていくとおもろいですね

exitを入力すると終わります

それなりに動きます

ちょっと機能を追加した最低限のやつ

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include <string.h>
#include <locale.h>
#define ctrl(x)           ((x) & 0x1f)
#ifndef SIZE_ALLOCATE
#define SIZE_ALLOCATE 1024
#endif

int access(const char*filename, int amode); // プロトタイプ宣言

int main(int argc, char **args) {
  // 変数宣言
  int h,w;
  bool help = true;
  char s[SIZE_ALLOCATE],
       *buffer = malloc(sizeof(char) * SIZE_ALLOCATE * 2048),
       c;
  FILE *fp;

  // 初期化
  setlocale(LC_ALL, "");
  echo();
  cbreak();
  raw();
  initscr();
  getmaxyx(stdscr, h, w);

  if (1 < argc){
    if (-1 == access(args[1], OK)) {
      perror("ファイルないですよ");
      endwin();
      exit(-1);
    }
    fp = fopen(args[1], "r");
    fscanf(fp, "%[^\EOF]c", buffer);
    fclose(fp);
  }

  do {
    // 更新前削除
    erase();

    // 描画関係
    move(0, 0);
    printw("start memory_size: %d, w: %d, h: %d\n", SIZE_ALLOCATE, w, h);
    if (help) {
      printw("help: Ctrl+q exit, Ctrl+o toggle Help\n");
      printw("      Ctrl+s save, Ctrl+l Input Enter (Please Key and Enter)\n");
      for (int i=0; i<w; i++) {
        printw("-");
      }
    }
    strcat(buffer, s);
    move(1 + (help ? 3 : 0), 0);
    addstr(buffer);
    move(h-1, 0);
    printw("type > ");

    // 再描画
    refresh();

    // 入力の後
    scanw("%[^\n]c", s);
    if (s[0] == ctrl('o')) {
      help = !help;
    }
    if (s[0] == ctrl('s')) {
      clear();
      move(h/2, w/2);
      printw("file name: ");
      scanw("%s", s);
      fp = fopen(s, "w");
      fputs(buffer, fp);
      fclose(fp);
      endwin();
      return 0;
    }
    if (s[0] == ctrl('l')) {
      s[0] = '\n';
    }
  } while(s[0] != ctrl('q'));
  endwin();
  return 0;
}

バグありですが、こうやって段々とエディターっぽくしていくとおもろいですね

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?